You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中自定义表格createColumnHelper的类型优化需求

解决createColumnHelper中cell/footer参数类型推断问题

要实现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类型的警告。

IDE截图1
IDE截图2

内容的提问来源于stack exchange,提问作者IncognitoUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:04:56