如何在TypeScript中根据属性名自动推断类型?
在TypeScript中根据属性名自动推断类型的实现方案
需求是:定义接口DataType和泛型接口ColumnType,让ColumnType中style函数的cellValue参数类型,根据propertyName对应的DataType属性类型自动推断。例如当propertyName: "name"时,cellValue应被推断为string类型。
原代码示例
interface DataType { id: "string"; name: "string"; quantity: number; price: number; type: "FT" | "QA"; } const allData: DataType[] = [ { id: "1", name: "one", quantity: 1, price: 1, type: "FT", }, { id: "2", name: "two", quantity: 2, price: 2, type: "QA", }, ]; interface CallbackParamsType<T> { cellValue: any; rowValue: T; data: T[]; } interface ColumnType<T> { header: "string"; propertyName: keyof T; style?: (params: CallbackParamsType<T>) => Record<string, string>; } const columns: ColumnType<DataType>[] = [ { header: "Id", propertyName: "id" }, { header: "Name", propertyName: "name", style: ({ rowValue, cellValue }) => { const x = cellValue; // 期望类型为string return {}; }, }, { header: "Quantity", propertyName: "quantity", style: ({ rowValue, cellValue }) => { const x = cellValue; // 期望类型为number return {}; }, }, { header: "Price", propertyName: "price", }, ];
实现方案
核心思路是通过增加泛型参数,建立propertyName与cellValue类型的关联:
- 给
CallbackParamsType增加泛型参数K(约束为keyof T),将cellValue的类型指定为T[K] - 给
ColumnType增加泛型参数K,让propertyName的类型为K,同时style函数的参数类型绑定为CallbackParamsType<T, K> - 利用TypeScript的自动推断能力,让每个列元素的
K类型根据propertyName自动确定
修改后的完整代码
interface DataType { id: string; // 修正原字面量类型问题,改为通用string类型(若需固定值可保留原定义) name: string; quantity: number; price: number; type: "FT" | "QA"; } const allData: DataType[] = [ { id: "1", name: "one", quantity: 1, price: 1, type: "FT", }, { id: "2", name: "two", quantity: 2, price: 2, type: "QA", }, ]; // 增加泛型参数K,关联DataType的属性类型 interface CallbackParamsType<T, K extends keyof T> { cellValue: T[K]; rowValue: T; data: T[]; } // 增加泛型参数K,绑定propertyName与style的参数类型 interface ColumnType<T, K extends keyof T> { header: string; // 修正原字面量类型问题,改为通用string类型 propertyName: K; style?: (params: CallbackParamsType<T, K>) => Record<string, string>; } // 自动推断每个列的K类型,也可通过satisfies语法显式约束类型 const columns = [ { header: "Id", propertyName: "id" }, { header: "Name", propertyName: "name", style: ({ rowValue, cellValue }) => { const x = cellValue; // 类型自动推断为string return {}; }, }, { header: "Quantity", propertyName: "quantity", style: ({ rowValue, cellValue }) => { const x = cellValue; // 类型自动推断为number return {}; }, }, { header: "Price", propertyName: "price", }, ] satisfies Array<ColumnType<DataType, keyof DataType>>;
说明
- 通过泛型参数
K,将propertyName的具体属性名与cellValue的类型强绑定,TypeScript会根据每个列的propertyName值自动推断出对应的属性类型 - 原代码中
header: "string"是字面量类型,限制header只能赋值为"string",实际场景中通常改为string类型以支持任意表头文本,若有特殊需求可保留原定义 - 使用
satisfies语法可以在保留自动推断的同时,确保数组元素符合ColumnType<DataType, keyof DataType>的类型约束
内容的提问来源于stack exchange,提问作者RanST
相关产品推荐
相关产品推荐

