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

如何为Tanstack Table的fuse.js自定义过滤函数声明FilterFn泛型类型?

如何为基于fuse.js的Tanstack Table自定义模糊搜索过滤函数正确声明泛型类型以解决TypeScript报错

问题背景

我为Tanstack Table编写了一个基于fuse.js的自定义模糊搜索过滤函数,但在为该函数定义类型时,TypeScript始终报错。我希望函数符合FilterFn<TData extends RowData>接口要求,目前代码中用any替代了泛型TData,需要替换为正确的泛型声明。

相关接口定义:

export interface FilterFn<TData extends RowData> {
    (row: Row<TData>, columnId: string, filterValue: any, addMeta: (meta: FilterMeta) => void): boolean;
    resolveFilterValue?: TransformFilterValueFn<TData>;
    autoRemove?: ColumnFilterAutoRemoveTestFn<TData>;
}

现有过滤函数代码:

/**
 * FilterFunction for Tanstack Table incorporating fuse's fuzzy search
 */
export const fuseFilterFn: FilterFn<any> = (
  row,
  columnId,
  filterValue,
  addMeta
) => {
  const searchPattern = filterValue.toString();

  const fuse = new Fuse([row.getValue(columnId)]);
  const searchResults = fuse.search(searchPattern);

  if (searchResults.length > 0) {
    // 若找到匹配结果,则该行视为符合条件
    addMeta({ searchResults }); // 可选:添加搜索结果的元数据
    return true;
  }

  return false;
};

表格组件代码:

interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[];
  data: TData[];
  columnFilters?: ColumnFilter[];
}

export function Table<TData, TValue>({
  data,
  columns,
  columnFilters = [],
}: DataTabelProps<TData, TValue>) {
  const [sorting, setSorting] = useState<ColumnSort[]>([]);
  const [filtering, setFiltering] = useState('');

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    state: {
      sorting: sorting,
      globalFilter: filtering,
      columnFilters: columnFilters,
    },
    globalFilterFn: fuseFilterFn,
    onSortingChange: setSorting,
    onGlobalFilterChange: setFiltering,
  });
}

解决方案

1. 将过滤函数改为泛型函数

把fuseFilterFn定义为接受TData extends RowData泛型参数的函数,让它返回对应类型的FilterFn<TData>,完美匹配接口要求:

import { FilterFn, Row, RowData, FilterMeta } from '@tanstack/react-table';
import Fuse from 'fuse.js';

/**
 * 集成fuse模糊搜索的Tanstack Table过滤函数
 */
export const fuseFilterFn = <TData extends RowData>(): FilterFn<TData> => {
  return (row, columnId, filterValue, addMeta) => {
    // 用String()替代toString(),避免null/undefined报错
    const searchPattern = String(filterValue);
    
    // 可添加fuse配置优化搜索效果,比如阈值、大小写敏感等
    const fuse = new Fuse([row.getValue(columnId)], {
      threshold: 0.4,
      includeScore: true,
    });
    const searchResults = fuse.search(searchPattern);

    if (searchResults.length > 0) {
      addMeta({ searchResults });
      return true;
    }

    return false;
  };
};

2. 在表格组件中正确使用泛型过滤函数

在useReactTable配置中,调用fuseFilterFn<TData>()生成对应表格数据类型的过滤函数,同时修正Props拼写错误(DataTabelProps改为DataTableProps):

import { useState } from 'react';
import { useReactTable, ColumnDef, ColumnSort, ColumnFilter, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, RowData } from '@tanstack/react-table';

interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[];
  data: TData[];
  columnFilters?: ColumnFilter[];
}

export function Table<TData extends RowData, TValue>({
  data,
  columns,
  columnFilters = [],
}: DataTableProps<TData, TValue>) {
  const [sorting, setSorting] = useState<ColumnSort[]>([]);
  const [filtering, setFiltering] = useState('');

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    state: {
      sorting,
      globalFilter: filtering,
      columnFilters,
    },
    // 传入当前表格的TData泛型,生成类型匹配的过滤函数
    globalFilterFn: fuseFilterFn<TData>(),
    onSortingChange: setSorting,
    onGlobalFilterChange: setFiltering,
  });

  // 表格渲染逻辑...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:25:33