元素隐式具有'any'类型,而类型是显式设置的



我有一个比较器函数sortBy,它用于按任何指定的字符串属性对对象T进行排序,以传递到数组中。排序函数:arr.sort(sortBy)

export const sortBy = <T>(property: string) : (a: T, b: T) => number => {
return (a: T, b: T) => {
if (a[property] < b[property]) return 1
else if (a[property] > b[property]) return -1
return 0
}
}

但是我收到这些错误:

元素隐式具有'any'类型,因为'string'类型的表达式不能用于索引'unknown'类型。

在类型为"未知"的索引签名上找不到参数类型为"string"的索引签名。ts(7053)

设置abany时功能生效

export const sortBy = <T>(property: string) : (a: T, b: T) => number => {
return (a: T, b: T) => {
if ((a as any)[property] < (b as any)[property]) return 1
else if ((a as any)[property] > (b as any)[property]) return -1
return 0
}
}

但是这个看起来很丑

T始终是一维对象但是设置sortBy = <T = Record<string, string>>(property: string)...给我同样的错误。

我不知道还有什么比这更好的表达方式了。

是否有其他更好的方法来写这个?

你需要绑定property和object,以确保property存在于object中。

选项1

export const sortBy =
<Prop extends PropertyKey>(property: Prop) =>
<Obj extends Record<Prop, unknown>>(a: Obj, b: Obj) => {
if (a[property] < b[property]) return 1
else if (a[property] > b[property]) return -1
return 0
}
sortBy('a')({ a: 42 }, { a: 43 }) // ok
sortBy('b')({ a: 42 }, { a: 43 }) // error

Obj扩展Record<Prop, unknown>。正如您可能已经注意到的,Prop在一开始就被推断出来了。Not TS知道Obj应该有Prop属性

选项2

export const sortBy = <T extends Record<string, unknown>>
(a: T, b: T) =>
(property: keyof T) => {
if (a[property] < b[property]) return 1
else if (a[property] > b[property]) return -1
return 0
}
sortBy({ a: 42 }, { a: 43 })('a') // ok
sortBy({ a: 42 }, { a: 43 })('b') // error

游乐场

现在TS意识到属性a存在于你的对象

最新更新