TypeScript元组首元素返回类型隐式推断验证问题
TypeScript类型推断验证实现问题
我需要实现如下TypeScript类型推断验证,核心需求是让validate函数的第二个参数数组中,每个元组的断言函数返回值类型必须和对应的验证器参数类型匹配——比如用validateNumber验证字符串类型的属性时,TypeScript能自动抛出错误。
现有代码:
interface Animal { name: string; color: string; age: number; } type Validator<T> = (data: T) => boolean; const validateString: Validator<string> = (data) => !!data?.length; const validateNumber: Validator<number> = (data) => data > 0; // 需实现类型推断的类型(当前版本无法实现期望校验) type ValidatorTuple<T> = [(data: T) => unknown, Validator<unknown>]; const validate = <T>(item: T, validator: ValidatorTuple<T>[]) => { for (const [predicate, validation] of validator) { const value = predicate(item); const result = validation(value); if (!result) return false; } return true; }; // 期望效果:第三个元组中用validateNumber验证d.name(string类型)应触发TS错误 const dog: Animal = { age: 12, color: "white", name: "josh", }; const isValid = validate(dog, [ [(d) => d.age, validateNumber], [(d) => d.color, validateString], [(d) => d.name, validateNumber], // 此处应触发TS错误 ]);
我尝试了多种TypeScript推断方式,但均无法实现上述期望的类型校验效果。
解决方案
要实现这个类型校验,需要让ValidatorTuple<T>关联断言函数的返回值类型和验证器的参数类型,具体可以通过泛型约束来实现:
interface Animal { name: string; color: string; age: number; } type Validator<T> = (data: T) => boolean; const validateString: Validator<string> = (data) => !!data?.length; const validateNumber: Validator<number> = (data) => data > 0; // 重新定义ValidatorTuple,用泛型K绑定断言返回值与验证器参数类型 type ValidatorTuple<T> = <K>([(data: T) => K, Validator<K>]); // 调整validate函数的参数类型,确保数组内每个元组的类型一致性 const validate = <T>(item: T, validator: Array<ValidatorTuple<T>[0]>) => { for (const [predicate, validation] of validator) { const value = predicate(item); const result = validation(value); if (!result) return false; } return true; }; const dog: Animal = { age: 12, color: "white", name: "josh", }; const isValid = validate(dog, [ [(d) => d.age, validateNumber], // 正常:number类型匹配Validator<number> [(d) => d.color, validateString], // 正常:string类型匹配Validator<string> [(d) => d.name, validateNumber], // TS错误:类型'string'的参数不能赋给类型'number'的参数 ]);
原理说明
- 给
ValidatorTuple<T>添加泛型K,K代表从T中提取的属性类型,让断言函数的返回值类型与验证器的参数类型强绑定。 - 将
validate函数的第二个参数定义为Array<ValidatorTuple<T>[0]>,允许数组包含任意属性对应的元组,但强制每个元组内部的类型必须一致。
内容的提问来源于stack exchange,提问作者Cosimo Chellini
相关产品推荐
相关产品推荐

