TypeScript排序对象数组报元素隐式any类型错误的解决方法
问题本质
这个报错来自TypeScript的静态类型校验:你将入参order定义为宽泛的string类型,但ProductsList接口只支持访问固定的几个已知属性,TS无法确认任意传入的字符串一定是ProductsList的合法键,更无法确认排除id、nome后剩余的属性值一定是可做减法的数值类型,因此抛出类型错误。
直接给接口加任意字符串索引签名的方案不可取,会破坏接口的类型约束,后续访问任意不存在的属性TS都不会报错,容易埋下隐患。
解决方案
方案1:从类型层面限制入参范围(最推荐)
用keyof操作符提取接口的合法属性键,再通过TS内置工具类型收窄到允许排序的数值属性范围,从入参阶段就杜绝非法值:
export interface ProductsList { id: boolean nome: string qtde: number valor: number valorTotal: number } // 提取ProductsList的所有属性键,排除非数值类型的id、nome,得到合法排序键的联合类型 type ValidSortKey = Exclude<keyof ProductsList, 'id' | 'nome'> const exampleFn = (productsData: ProductsList[], order: ValidSortKey) => { // 此处无需额外判断order是否合法,类型系统已做校验 // TS可自动推导a[order]、b[order]为number类型,减法运算无类型错误 productsData.sort((a, b) => b[order] - a[order]) }
调用函数时,TS会自动校验传入的order是否在'qtde' | 'valor' | 'valorTotal'范围内,传错值会直接在编译阶段提示。
方案2:运行时校验+类型收窄(适合order来自外部输入的场景)
如果order的值来自接口返回、用户输入等无法提前确定类型的场景,就在函数内部做一层运行时校验,同时通过TS的类型推导自动收窄类型:
export interface ProductsList { id: boolean nome: string qtde: number valor: number valorTotal: number } const exampleFn = (productsData: ProductsList[], order: string) => { // 列出所有允许做数值排序的属性键 const validNumericKeys = ['qtde', 'valor', 'valorTotal'] as const // 传入的order不在合法范围内直接终止逻辑 if (!(validNumericKeys as readonly string[]).includes(order)) { return } // 此处TS会自动将order的类型收窄为合法排序键联合类型,无报错 productsData.sort((a, b) => b[order] - a[order]) }
内容的提问来源于stack exchange,提问作者Berg_Durden
相关产品推荐
相关产品推荐

