我正在使用打字稿进行类型检查功能。
const checkType = <T>(value: unknown, isTypeFn: (value: unknown) => value is T): T => {
if (!isTypeFn(value)) {
console.error(`${isTypeFn} ${value} does not have correct type`);
throw new Error(`${value} does not have correct type`);
}
return value;
};
const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
const isString = (value: unknown): value is string => typeof value === 'string';
const isNumber = (value: unknown): value is number => typeof value === 'number';
const isNull = (value: unknown): value is null => value === null;
Run Code Online (Sandbox Code Playgroud)
我可以像下面这样使用它。
const a = await getNumber() // this should be number
const numA: number = checkType(a, isNumber); // numA is number or throw Error!
Run Code Online (Sandbox Code Playgroud)
我想扩展 checkType 函数,如下所示。
const b = await getNumberOrString();
const bNumOrString: number | string = checkType(b, isNumber, isString);
const bNumOrBoolean: number | boolean = checkType(b, isNumber, isBoolean);
const bStringOrNull: string | null = checkType(b, isString, isNull);
Run Code Online (Sandbox Code Playgroud)
如何改进 checkType 使其像这样工作?
该函数checkType需要一个剩余参数。我们就这样称呼它吧isTypeFns。isTypeFns是一个泛型类型参数T,它将是带有类型谓词的函数数组。
const checkType = <
T extends ((value: unknown) => value is any)[]
>(value: unknown, ...isTypeFns: T): CheckType<T> => {
if (isTypeFns.some(fn => fn(value))) {
console.error(`${value} does not have correct type`);
throw new Error(`${value} does not have correct type`);
}
return value as CheckType<T>;
};
Run Code Online (Sandbox Code Playgroud)
实施过程非常简单。您只需检查其中的函数之一是否isTypeFns返回true给定的value.
返回类型再次变得更加棘手。我们需要采用T并推断类型谓词类型的并集。
type CheckType<T extends ((value: unknown) => value is any)[]> =
T[number] extends ((value: unknown) => value is infer U)
? U
: never
Run Code Online (Sandbox Code Playgroud)
我们使用它作为函数的返回类型。当涉及到return实现的声明时,TypeScript 无法理解这种复杂的类型。这就是为什么我在那里添加了一个断言。
const b = "b" as number | string;
const bNumOrString = checkType(b, isNumber, isString);
// ^? const bNumOrString: string | number
const bNumOrBoolean = checkType(b, isNumber, isBoolean);
// ^? const bNumOrBoolean: number | boolean
const bStringOrNull = checkType(b, isString, isNull);
// ^? const bStringOrNull: string | null
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |