如何使用括号表示法中的 typeof 属性

How to use the typeof property from bracket notation

我正在学习 TS,我正在创建一个排序函数,该函数使用参数作为键并使用括号表示法对我的对象数组进行排序。 上面的代码运行良好,但如果我想在未来扩展,我应该添加每个条件。我想通过我想使用的键值的类型来验证。

我尝试了类似上面的代码,它可以验证,但 TS 不断抛出错误 property/methods inside IF are not valid 因为它从我界面的每个键中获取所有现有类型,而不仅仅是真正能过关的

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 调用,保存 ab 中的 属性 值以分隔变量,然后测试类型以找到正确的比较。

例如:

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')
    })
}

See playground