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

如何为封装@tanstack/react-table的自定义组件正确定义TS类型

解决方案

报错核心原因

  • 从@tanstack/table-core/src/types这种内部非公开路径引入TableGenerics做泛型约束,内部类型不属于稳定公开API,和useTableInstance返回的实例泛型结构不匹配
  • 错误使用core包导出的TableInstance类型,React适配版的表格实例类型应该从@tanstack/react-table根路径引入,直接从core包引入会丢失React相关的渲染类型定义
  • 泛型约束冗余,不需要手动继承TableGenerics,官方公开的实例类型会自动处理泛型推断

修改后的GridTable组件类型定义

import React from 'react';
// 仅从包根路径引入公开类型,不要引用内部src路径的类型
import type { Table } from '@tanstack/react-table';

type GridTableProps<TData> = {
  table: Table<TData>
}

// 泛型只需要约束行数据类型即可
export function GridTable<TData>({ table }: GridTableProps<TData>) {
  return <div>
    <table border={1}>
      <thead>
      {table.getHeaderGroups().map(headerGroup => (
        <tr key={headerGroup.id}>
          {headerGroup.headers.map(header => (
            <th key={header.id} colSpan={header.colSpan}>
              {header.isPlaceholder ? null : header.renderHeader()}
            </th>
          ))}
        </tr>
      ))}
      </thead>
      <tbody>
      {table.getRowModel().rows.map(row => (
        <tr key={row.id}>
          {row.getVisibleCells().map(cell => (
            <td key={cell.id}>{cell.renderCell()}</td>
          ))}
        </tr>
      ))}
      </tbody>
      <tfoot>
      {table.getFooterGroups().map(footerGroup => (
        <tr key={footerGroup.id}>
          {footerGroup.headers.map(header => (
            <th key={header.id} colSpan={header.colSpan}>
              {header.isPlaceholder ? null : header.renderFooter()}
            </th>
          ))}
        </tr>
      ))}
      </tfoot>
    </table>
  </div>;
}

调用方式

修改后不需要任何as any类型断言,直接传入useTableInstance返回的实例即可通过类型校验:

import { FC } from 'react';
import { createTable, useTableInstance, getCoreRowModel } from '@tanstack/react-table';
import { Person, defaultData } from './data';
import { GridTable } from './GridTable';

const table = createTable().setRowType<Person>()

export const defaultColumns = [
  table.createDataColumn('firstName', {
    cell: info => info.getValue(),
    footer: props => props.column.id,
  }),
  table.createDataColumn(row => row.lastName, {
    id: 'lastName',
    cell: info => info.getValue(),
    header: () => <span>Last Name</span>,
    footer: props => props.column.id,
  }),
  table.createDataColumn('age', {
    header: () => 'Age',
    footer: props => props.column.id,
  }),
  table.createDataColumn('visits', {
    header: () => <span>Visits</span>,
    footer: props => props.column.id,
  }),
  table.createDataColumn('status', {
    header: 'Status',
    footer: props => props.column.id,
  }),
  table.createDataColumn('progress', {
    header: 'Profile Progress',
    footer: props => props.column.id,
  }),
]

export const TableDemo: FC = () => {
  const instance = useTableInstance(table, {
    data: defaultData,
    columns: defaultColumns,
    getCoreRowModel: getCoreRowModel(),
  })

  return <GridTable table={instance} />
};

额外说明

  • 所有TanStack Table相关类型都从你使用的适配包根路径引入(比如React技术栈就从@tanstack/react-table引,Vue就从@tanstack/vue-table引),不要直接引用core包或者包内部src路径的类型,这类类型不属于稳定公开API,版本迭代时很容易出现结构不兼容问题
  • 常规场景下Table<TData>只需要传入行数据类型作为泛型参数即可,所有列、单元格、渲染相关的类型会自动推断。如果有自定义列元数据的需求,可以传入第二个泛型参数声明额外的列属性类型
  • 旧版本中的TableInstance类型已经是Table类型的别名,直接使用Table即可获得完整的类型支持

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:51:43