如何基于同对象属性推断回调值类型?DataGrid组件类型问题
问题原因与解决方案
你的问题出在DataGridProps的泛型设计上:当前K被声明为整个组件的泛型参数,这意味着所有列的K会被推断为keyof T的联合类型,导致formatter的value类型变成T[keyof T](也就是所有字段值的联合),而不是单个字段的具体类型。
修复步骤
- 保留基础的
ColumnDefinition类型:
interface ColumnDefinition<T extends object, K extends keyof T> { field: K; formatter: (value: T[K]) => string; }
- 定义一个辅助类型,生成针对
T所有键的列定义联合类型:
type ColumnFor<T extends object> = { [K in keyof T]: ColumnDefinition<T, K>; }[keyof T];
这个类型会遍历T的每个键,生成对应字段的专属列定义,最终合并成联合类型。
- 修改
DataGridProps,仅保留T作为泛型参数,同时让columns是上述联合类型的数组:
interface DataGridProps<T extends object> { rows: T[]; columns: ColumnFor<T>[]; }
验证效果
现在使用组件时,每个列的formatter参数会自动推断对应字段的具体类型:
interface User { name: string; isActive: boolean; id: number; } const users: User[] = [ {name: 'John', isActive: true, id: 1}, {name: 'Mike', isActive: false, id: 2} ]; // 每个formatter的value类型会正确推断: // name对应的value是string,id对应的是number,isActive对应的是boolean <DataGrid rows={users} columns={[ {field: 'name', formatter: (value) => value.toUpperCase()}, {field: 'id', formatter: (value) => value.toString()}, {field: 'isActive', formatter: (value) => value ? '活跃' : '禁用'} ]}/>
补充说明
如果需要支持可选字段或自定义额外列属性,直接在ColumnDefinition中添加对应属性即可,辅助类型ColumnFor<T>会自动继承这些属性,不会影响类型推断的准确性。
内容的提问来源于stack exchange,提问作者Facundo Rodriguez
相关产品推荐
相关产品推荐

