如何为react-data-table-component的自定义sortFunction正确定义类型?
问题描述
我需要为react-data-table-component的自定义排序方法添加类型定义,目前selector参数使用了any类型,希望移除该any类型,但不确定应为其指定何种类型。
完整代码如下:
interface IAlergia { AlergiaId: number; Descripcion: string; Reaccion: string; Estatus: string; Comprador: string; CompradorId: number; } const Alergia = () => { //Custom sort since the component uses Array.Sort and it does not take in account the lowercase sorting... const customSort = (rows: IAlergia[], selector: any, direction: string) => { return rows.sort((a, b) => { // use the selector to resolve your field names by passing the sort comparators const aField = selector(a).toLowerCase(); const bField = selector(b).toLowerCase(); let comparison = 0; if (aField > bField) { comparison = 1; } else if (aField < bField) { comparison = -1; } return direction === 'desc' ? comparison * -1 : comparison; }); }; return( <DataTable columns={columns} data={options} sortFunction={customSort}/> ) } export default Alergia;
解决方案
1. 给selector指定正确类型
selector本质是一个接收IAlergia对象、返回字符串的函数——因为你在排序逻辑里调用了.toLowerCase(),说明它的返回值必须是字符串类型。所以类型可以定义为(row: IAlergia) => string。
修改后的customSort函数:
const customSort = ( rows: IAlergia[], selector: (row: IAlergia) => string, direction: 'asc' | 'desc' ) => { // 注意:Array.sort会原地修改原数组,这里先复制一份再排序,避免污染原数据 return [...rows].sort((a, b) => { const aField = selector(a).toLowerCase(); const bField = selector(b).toLowerCase(); let comparison = 0; if (aField > bField) { comparison = 1; } else if (aField < bField) { comparison = -1; } return direction === 'desc' ? comparison * -1 : comparison; }); };
2. 额外优化建议
- 把
direction的类型从string改成'asc' | 'desc',这样能强制传入合法的排序方向,避免无效字符串导致的bug。 - 原代码中
rows.sort()会直接修改传入的rows数组,可能导致原数据被意外篡改。通过[...rows]复制新数组再排序,能保证原数据的不可变性。
3. 支持数字类型排序(可选)
如果你的表格有数字类型列(比如AlergiaId、CompradorId)需要排序,可以把selector的类型改成支持返回字符串或数字的联合类型,同时优化排序逻辑:
const customSort = ( rows: IAlergia[], selector: (row: IAlergia) => string | number, direction: 'asc' | 'desc' ) => { return [...rows].sort((a, b) => { const aField = selector(a); const bField = selector(b); let comparison = 0; if (typeof aField === 'string' && typeof bField === 'string') { // 用localeCompare处理字符串排序,比直接比较更严谨(支持多语言) comparison = aField.toLowerCase().localeCompare(bField.toLowerCase()); } else if (typeof aField === 'number' && typeof bField === 'number') { // 数字直接相减,逻辑更简洁 comparison = aField - bField; } return direction === 'desc' ? comparison * -1 : comparison; }); };
内容的提问来源于stack exchange,提问作者Jorge F
相关产品推荐
相关产品推荐

