【问题标题】:Typescript iterate over an array of interface fieldsTypescript 遍历接口字​​段数组
【发布时间】:2021-12-12 07:28:45
【问题描述】:

我想使用一个数组来遍历接口属性,但是它在 forEach 函数上抛出了一个 ts 编译错误:

interface A {
  foo: string
  bar: string
  baz: string
}

function fn(obj: A) {
  ;["foo", "bar"].forEach( (prop: keyof A) => {
    obj[prop] // do stuff
  })
}

错误:

'(prop: keyof A) => void' 类型的参数不能分配给'(value: string, index: number, array: string[]) => void' 类型的参数。 参数“prop”和“value”的类型不兼容。 类型“字符串”不可分配给类型“keyof A”

这样的东西会起作用,但感觉是多余的:

function fn(obj: A) {
  const ar: (keyof A)[] = ["foo", "bar"]
  ar.forEach( (prop: keyof A) => {
    obj[prop] // do stuff
  })
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    TypeScript 将 ["foo", "bar"] 的类型推断为 string[],不能将其分配给类型 keyof A,因为它可能包含不属于该类型的字符串。如果你告诉 TypeScript 你的数组是(keyof A)[] 类型,那么它就可以工作。例如:

    interface A {
      foo: string
      bar: string
      baz: string
    }
    
    function fn(obj: A) {
      ;(["foo", "bar"] as (keyof A)[]).forEach( (prop) => {
        obj[prop] // do stuff
      })
    }
    

    TypeScript playground

    不过,该示例使用了类型断言,最好尽可能避免使用,因为它绕过了 TypeScript 的类型检查。你可以通过使用类似这样的东西来避免这种情况,如果你试图在你的数组中放入一个不是A的属性名称之一的字符串,它将拒绝编译:

    interface A {
      foo: string
      bar: string
      baz: string
    }
    
    function fn(obj: A) {
      let values: (keyof A)[] = ['foo', 'bar'];
      values.forEach( (prop) => {
        obj[prop] // do stuff
      })
    }
    

    TypeScript playground

    【讨论】:

    • 这太完美了,谢谢!没有意识到我可以这样推断参数类型。
    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2020-11-24
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    相关资源
    最近更新 更多