【问题标题】:TypeScript: Why having a `keyof` here can solve this issueTypeScript:为什么在这里有一个 `keyof` 可以解决这个问题
【发布时间】:2021-02-07 00:20:18
【问题描述】:

我正在尝试编写一个函数来返回对象中的值数组

let obj = {
  a: 1,
  b: 2,
  c: 3,
}

const r = Object.keys(obj).map((key) => {
  let val = obj[key]
  return val
})

这里 TS 编译器显示错误提示

元素隐含地具有“任何”类型,因为类型的表达式 'string' 不能用于索引类型 '{ a: number; b:号码; C: 数字; }'。没有带有“字符串”类型参数的索引签名 在类型 '{ a: number; b:号码; c:号码; }'.ts(7053)

我无法解读它的含义,但我认为它与 key 是一个字符串有关。所以我尝试了这个

let obj = {
  a: 1,
  b: 2,
  c: 3,
}

const r = Object.keys(obj).map((key) => {
  let val = obj[key as keyof typeof obj] // the error now is gone
  return val
})

console.log('r', r)

现在没有错误了。我不确定为什么。我所知道的是keyof 会产生obj 上允许的属性名称的类型,但我不知道typeof 在这里的用途

【问题讨论】:

    标签: typescript


    【解决方案1】:

    Typescript 推断您的 obj 对象的类型为:

    type Obj = {
      a: number
      b: number
      c: number
    }
    

    这也可以表示为:

    type Obj = {[key in 'a' | 'b' | 'c']: number};
    

    'a' | 'b' | 'c'string 的子类型。但是,当您使用Object.keys(obj) 时,typescript 会推断此处的返回类型为string[],而不是('a' | 'b' | 'c')[]。这就是它抱怨No index signature with a parameter of type 'string' was found on type '{ a: number; b: number; c: number; }' 的原因——因为您不能使用任何stringobj 中查找值,而是需要使用特定的键。

    keyof 运算符将类型作为输入,并返回提供的键。您需要typeof 的原因是推断对象的类型(否则您将使用keyof obj,打字稿无法理解obj 不是类型)

    keyof typeof obj 被推断为"a" | "b" | "c"

    Keyof - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types

    Typeof - https://mariusschulz.com/blog/type-queries-and-typeof-in-typescript#typescripts-type-queries

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 2021-01-17
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 2010-11-25
      • 2015-06-25
      相关资源
      最近更新 更多