我正在学习TS,我正在创建一个排序函数,该函数使用参数作为使用括号符号的键来排序我的对象数组。上面的代码工作得很好,但如果我想在将来扩展,我应该添加每个条件。我想通过我想要使用的键值的类型来验证。
我尝试了上面的代码,它可以进行验证,但是TS不断抛出错误,IF中的属性/方法无效,因为它从接口的每个键中获取所有现有类型,而不仅仅是那些真正可以通过条件
的类型if(typeof arr[prop] === "string")
if(arr[prop] instanceof String)
if(arr[prop].constructor.name === "String")
代码
interface Person{
name: string,
age: number,
isAlive: boolean}
const myArr = [
{name: 'Tomás',
age: 24,
isAlive: true},
{name: 'Kate',
age: 12,
isAlive: true},
{name: 'Brad',
age: 54,
isAlive: false},
{name: 'Angelica',
age: 64,
isAlive: true},
]
function myFn(
arr: Person[],
orderBy: keyof Person): Person[] {
if(orderBy === 'name'){
return arr.sort((a,b) => a[orderBy].localeCompare(b[orderBy]));
}
else if (orderBy === "age") {
return arr.sort((a, b) => a[orderBy] - b[orderBy]);
}
else if (orderBy === "isAlive") {
return arr.sort(value => value[orderBy] ? -1 : 1)
}
else {
return [];
}
}
const byAlive = myFn(myArr, "isAlive");
console.log(byAlive)
const byAge = myFn(myArr, "age");
console.log(byName)
const byName = myFn(myArr, "name");
console.log(byName)
提前感谢,对不起我的英语,我不是母语:)如果我有不清楚的地方,或者你不能理解我,请让我知道,这样我就能写得更好。
首先,Typescript很难通过动态属性访问来缩小类型,比如:
if (typeof person[prop] === 'string') person[prop].toUpperCase() // error
你可以通过将person[prop]
的结果赋值给一个变量,然后使用这个变量,让Typescript更容易做到这一点。例如:
const value = person[prop]
if (typeof value === 'string') value.toUpperCase() // works
那么,只做一个array.sort
调用,你保存属性值从a
和b
分离变量,然后测试类型找到适当的比较。
例如:
function myFn(
arr: Person[],
orderBy: keyof Person
): Person[] {
return arr.sort((aPerson, bPerson) => {
const a = aPerson[orderBy]
const b = bPerson[orderBy]
if (typeof a === 'string' && typeof b === 'string') {
return a.localeCompare(b)
}
if (typeof a === 'number' && typeof b === 'number') {
return a - b
}
if (typeof a === 'boolean' && typeof b === 'boolean') {
return a ? 1 : -1
}
throw Error('unsupported value type')
})
}
看到操场