基于其他Prop值推导React组件Prop类型:Table组件类型优化
React Table组件类型优化:让renderCell参数类型随key自动推导
当前你定义的React Table组件类型存在一个问题:renderCell的第一个参数value无法根据列的key值自动匹配对应的数据类型,只能拿到所有属性类型的联合。下面是优化方案,让每个列的renderCell参数类型能精准对应其key指向的属性类型。
原始类型定义
export interface ColumnType<ItemType, Key extends keyof ItemType = keyof ItemType> { header: string; key?: keyof ItemType; renderCell: (value: ItemType[Key] | undefined, item: ItemType, index: number) => React.ReactNode; } export interface TableProps<ItemType extends object> { data: ItemType[]; columns: ColumnType<ItemType>[]; }
优化后的类型定义
import React from 'react'; // 针对单个属性Key的列类型,绑定Key与value类型 type ColumnForKey<ItemType, Key extends keyof ItemType> = { header: string; key: Key; // 强制必填key,确保类型绑定 renderCell: (value: ItemType[Key], item: ItemType, index: number) => React.ReactNode; }; // 支持无key的自定义列(可选保留) type CustomColumn<ItemType> = { header: string; key?: never; renderCell: (value: undefined, item: ItemType, index: number) => React.ReactNode; }; // 合并两种列类型,支持带key的精准列和自定义列 export type ColumnType<ItemType> = ColumnForKey<ItemType, keyof ItemType> | CustomColumn<ItemType>; export interface TableProps<ItemType extends object> { data: ItemType[]; columns: ColumnType<ItemType>[]; }
效果演示
当使用优化后的类型定义时,TypeScript会自动根据key值推导renderCell的参数类型:
interface Person { firstName: string; age: number; } <Table data={[ { firstName: '张三', age: 25 }, { firstName: '李四', age: 30 }, ]} columns={[ { header: '姓名', key: 'firstName', renderCell: (v) => v, // v的类型自动推断为string }, { header: '年龄', key: 'age', renderCell: (v) => v.toString(), // v的类型自动推断为number }, { header: '自定义信息', renderCell: (_, item) => `${item.firstName} - ${item.age}岁`, // value为undefined,item为Person类型 }, ]} />
优化原理
原始定义中,ColumnType的泛型参数Key会被推断为keyof ItemType的联合类型,导致renderCell的value是所有属性类型的集合,无法做到单个列的精准类型匹配。
优化方案通过联合类型拆分,将每个列对应到ItemType的单个属性Key上,TypeScript会对数组中的每个列元素进行类型窄化,从而自动推导renderCell的参数类型。如果不需要指定key,则对应自定义列的类型规则。
内容的提问来源于stack exchange,提问作者Victor Wang
相关产品推荐
相关产品推荐

