TypeScript:如何为含String/Number构造函数的数组定义正确类型
解决TypeScript中构造函数与处理函数的类型匹配问题
要解决这个问题,核心是让TypeScript能够正确关联数组中构造函数和对应处理函数的类型,同时确保函数参数与返回值的类型安全。以下是具体实现方案:
1. 重新定义模式类型为联合类型
将Pattern定义为明确的联合类型,分别对应String和Number构造函数的场景,确保每个模式的构造函数与处理函数参数严格绑定:
type Pattern = | [typeof String, (val: string) => unknown] | [typeof Number, (val: number) => unknown];
2. 使用as const断言锁定数组类型
在定义patterns数组时添加as const,让TypeScript推断每个元素的具体类型(而非模糊的联合类型),保留构造函数与处理函数的关联关系:
const patterns = [ [String, (s: string) => s.length], // 明确接收string,返回number [Number, (n: number) => n + 1], // 明确接收number,返回number ] as const;
3. 优化match函数的泛型与类型推导
为match函数添加泛型约束,让返回值自动推导为所有处理函数返回值的联合类型,同时通过类型断言解决循环中TypeScript无法自动缩小类型的问题:
function match<P extends readonly Pattern[]>( value: string | number, patterns: P ): ReturnType<P[number][1]> { for (const [ctor, handler] of patterns) { if (value.constructor === ctor) { // 类型断言确保处理函数参数与value类型匹配 return handler(value as never) as ReturnType<P[number][1]>; } } throw new Error("No matching pattern found."); }
4. 验证类型安全
现在无需//@ts-ignore,TypeScript可以正确推断类型:
// testingResult的类型被自动推断为number const testingResult = match(123456, patterns); console.log(testingResult); // 输出123457
如果修改处理函数的返回类型(比如一个返回string,一个返回number),testingResult的类型会自动更新为string | number,完全符合预期。
内容的提问来源于stack exchange,提问作者MichalZard
相关产品推荐
相关产品推荐

