TypeScript中自定义表格createColumnHelper的类型优化需求
要实现cell和footer参数的类型自动推断(包括嵌套对象场景),需要通过泛型绑定accessor的返回值类型,替换掉原来的any类型。以下是具体修改方案:
1. 修改columnHelper.ts
import { ReactElement } from "react"; // 新增泛型V,标记accessor返回值的类型 export type Column<T, V> = { header: string | (() => ReactElement); accessor: (row: T) => V; cell?: (prop: V) => ReactElement | string; footer?: (prop: { column: Column<T, V> }) => ReactElement | string; }; export const createColumnHelper = <T>() => { return { // 泛型V自动推断accessor的返回类型 accessor: <V>( accessor: keyof T | ((row: T) => V), column: { header: string | (() => ReactElement); cell?: (prop: V) => ReactElement | string; footer?: (prop: { column: Column<T, V> }) => ReactElement | string; } ): Column<T, V> => { return { header: column.header, accessor: (row: T) => typeof accessor === "function" ? (accessor as (row: T) => V)(row) : (row[accessor] as V), cell: column.cell, footer: column.footer, }; } }; };
修改说明
- 给
Column类型添加第二个泛型V,将accessor的返回值类型与cell/footer的参数类型绑定,彻底替换any; accessor方法新增泛型V,TypeScript会根据传入的键名(如'firstName')或自定义函数(如row => row)自动推断V的具体类型;- 修正footer的参数类型,匹配组件中实际传入的
{ column }结构,保证类型一致性。
2. 组件中使用效果
修改后,TableComponents.tsx中的cell参数会自动获得正确类型:
import React from "react"; import { createColumnHelper } from "./columnHelper"; type Person = { firstName: string lastName: string age: number visits: number status: string progress: { ok?: number; no?: string } } const DATA: Person[] = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: { ok: 50 }, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: { no: 'bad' }, }, ] const columnHelper = createColumnHelper<Person>(); const columns = [ // cell的val自动推断为string类型 columnHelper.accessor('firstName', { header: 'First Name', cell: val => val, }), // cell的prop自动推断为progress的类型,能提示ok/no属性 columnHelper.accessor('progress', { header: 'Progress', cell: prop => prop.ok, }), // cell的prop自动推断为Person类型,能提示age等属性 columnHelper.accessor(row => row, { header: () => <span>Age</span>, cell: prop => <span>{prop.age}</span>, }), ]; const TableComponent: React.FC = () => { return ( <table> <thead> <tr> {columns.map((column, index) => ( <th key={index}> {typeof column.header === "function" ? column.header() : column.header} </th> ))} </tr> </thead> <tbody> {DATA.map((row, rowIndex) => ( <tr key={rowIndex}> {columns.map((column, colIndex) => ( <td key={colIndex}> {column.cell ? column.cell(column.accessor(row)) : column.accessor(row)} </td> ))} </tr> ))} </tbody> <tfoot> <tr> {columns.map((column, index) => ( <td key={index}> {column.footer ? column.footer({ column }) : null} </td> ))} </tr> </tfoot> </table> ); }; export default TableComponent;
此时IDE中会正确显示cell参数的类型,比如处理progress字段时,能自动提示ok和no属性,不再出现any类型的警告。


内容的提问来源于stack exchange,提问作者IncognitoUser
相关产品推荐
相关产品推荐

