TypeScript对象数组使用localeCompare排序出现类型错误如何解决?
问题原因
你遇到的TS报错是因为entries类型的属性值是string | number联合类型,number类型不存在localeCompare方法,静态类型检查不通过。以下是三种常用解决方案:
方案1:运行时类型收窄(最稳妥,兼容所有场景)
无需强制定类型,运行时自动判断属性类型,不会出现非预期报错:
;(() => { type entries = { [key: string]: string | number } const data: entries[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 2} ] const index = 'key' const order: entries[] = data.sort((a, b) => { const valA = a[index] const valB = b[index] if (typeof valA === 'string' && typeof valB === 'string') { return valA.localeCompare(valB) } // 不需要兼容数字排序的话可以直接转字符串调用 return String(valA).localeCompare(String(valB)) }) console.log(order) })()
方案2:类型断言(100%确认当前key对应值为string时使用)
代码更简洁,直接告知TS属性类型,跳过静态检查:
;(() => { type entries = { [key: string]: string | number } const data: entries[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 2} ] const index = 'key' const order: entries[] = data.sort((a, b) => (a[index] as string).localeCompare(b[index] as string)) console.log(order) })()
方案3:类型层面约束key范围(推荐,从根源避免传错key)
重构类型定义,约束传入的key只能对应string类型的属性,传错key直接在编码阶段提示:
;(() => { type Entry = { key: string, number: number } // 提取所有值为string类型的键 type StringKeys<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T] const data: Entry[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 2} ] // index类型被约束为只能是'string'类型的键,传'number'会直接报错 const index: StringKeys<Entry> = 'key' const order: Entry[] = data.sort((a, b) => a[index].localeCompare(b[index])) console.log(order) })()
内容的提问来源于stack exchange,提问作者Álvaro
相关产品推荐
相关产品推荐

