TypeScript中如何让ICol的formatValue参数类型与accessor关联?
解决TypeScript泛型接口中accessor与formatValue参数类型关联的问题
原接口设计里,当指定accessor为具体字段时,formatValue的参数类型无法和该字段的类型绑定,而是变成所有可能属性类型的联合。问题根源在于泛型参数K被设定为keyof T的联合类型,导致T[K]自动展开为所有属性类型的集合。
解决方案:用映射类型生成强关联的联合类型
重新定义ICol为联合类型,每个成员对应T的一个具体键,让accessor和formatValue的参数类型强绑定:
import type { JSX } from 'react'; // 若用到JSX.Element需导入该类型 type ICol<T extends Record<string, any>> = // 覆盖所有指定accessor的场景:每个键对应独立的类型成员 | { [K in keyof T]: { accessor: K; formatValue?: (value: T[K]) => JSX.Element | string | number; } }[keyof T] // 保留不指定accessor的合法场景 | { accessor?: never; formatValue?: never; };
代码验证
用测试类型验证类型提示是否符合预期:
// 测试用数据类型 type TestData = { a: number; b: string; c: Date; }; // 指定accessor为'a'时,formatValue的value自动提示为number类型 const colA: ICol<TestData> = { accessor: 'a', formatValue: (value) => { return value.toFixed(2); // 此处value类型为number,可直接调用number专属方法 } }; // 指定accessor为'b'时,value自动提示为string类型 const colB: ICol<TestData> = { accessor: 'b', formatValue: (value) => { return value.toUpperCase(); // 此处value类型为string,可直接调用string专属方法 } }; // 不指定accessor的合法示例 const colEmpty: ICol<TestData> = {};
原理说明
通过{ [K in keyof T]: ... }[keyof T]的映射类型,我们为T的每个键生成一个独立的对象类型,再将这些类型合并为联合类型。当TypeScript推断到具体的accessor值时,会自动缩小联合类型到对应的成员,从而让formatValue的参数类型精准匹配accessor对应的字段类型。
内容的提问来源于stack exchange,提问作者Fraga
相关产品推荐
相关产品推荐

