如何为接收数组的TypeScript泛型函数添加类型校验
TypeScript泛型函数数组参数的完整属性类型校验
我有一个接收数组参数的TypeScript泛型函数,它能通过传入的数组构造指定泛型类型的对象,功能正常,但需要添加类型校验——当数组的key无法覆盖泛型类型的全部属性时,抛出TypeScript错误。
现有接口定义
interface OutputType { id: string; name: string; age: number; } interface ArrayType { key: string; value: any; }
现有泛型函数
function TestType<T>(array: ArrayType[]): T { let newObj = {} as T; array.forEach((arrayItem) => { newObj[arrayItem.key as keyof T] = arrayItem.value; }); return newObj; }
期望的校验行为
- 缺少属性的数组应该触发TypeScript错误:
// 缺少id属性,应该报错 const array = [ { key: "name", value: "TestName", }, { key: "age", value: 12, }, ] as ArrayType[];
- 包含全部属性的数组应该通过校验:
// 包含所有属性,应该通过 const array = [ { key: "id", value: "1", }, { key: "name", value: "TestName", }, { key: "age", value: 12, }, ] as ArrayType[];
实现方案
要实现这个校验,需要定义自定义类型来强制数组覆盖泛型的所有属性,同时还能自动校验value的类型匹配:
定义单个数组项的泛型类型
生成与泛型T属性一一对应的{key: 属性名, value: 属性类型}联合类型:type ArrayItem<T> = { [K in keyof T]: { key: K; value: T[K] }; }[keyof T];定义强制包含所有属性的数组类型
利用TypeScript的类型约束,确保数组必须包含T的每一个属性对应的项:type RequiresAllKeys<T> = Array<ArrayItem<T>> & { [K in keyof T]: Extract<ArrayItem<T>, { key: K }>; };修改泛型函数的参数类型
替换原有的ArrayType[]为自定义校验类型:function TestType<T>(array: RequiresAllKeys<T>): T { let newObj = {} as T; array.forEach((arrayItem) => { newObj[arrayItem.key] = arrayItem.value; }); return newObj; }
测试验证
现在不需要再用as ArrayType[]断言数组,TS会自动完成校验:
// 报错:类型不匹配,提示缺少key为"id"的项 const invalidArray = [ { key: "name", value: "TestName" }, { key: "age", value: 12 }, ]; // 校验通过,且value类型自动匹配OutputType的属性要求 const validArray = [ { key: "id", value: "1" }, { key: "name", value: "TestName" }, { key: "age", value: 12 }, ]; const result = TestType<OutputType>(validArray); // result类型为OutputType,属性类型完全匹配
内容的提问来源于stack exchange,提问作者Mr. Scary
相关产品推荐
相关产品推荐

