如何为封装@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
相关产品推荐
相关产品推荐

