动态更改对象属性时打字稿错误

时间:2021-04-22 16:29:20

标签: typescript types

当我尝试根据动态变量更新对象的属性时遇到问题。我在 stackoverflow 上查看了更多答案,但无法找到解决方案。

export interface Bikes {
  totals: Array<number>;
}

interface Products {
  cars:  Cars;
  bikes:  Bikes;
}

export interface RawData {
    products: Products
}

demo( data: RawData ) {
  // data.products contains both "cars" and "bikes" properties.
  for (var type in data.products) { 
    for (var product in data.products[type].totals) {// <-- error here
                        -------------
     ....
   }
}
<块引用>

元素隐式具有 'any' 类型,因为类型 'string' 的表达式不能用于索引类型 'Products'。 在类型“产品”上找不到参数类型为“字符串”的索引签名。

我也试过使用:

export interface RawData {
    products: keyof Products
}

然后错误出现在 data.products[type].totals

<块引用>

'string' 类型不存在属性 'bikes'。

1 个答案:

答案 0 :(得分:2)

在您的情况下,变量 type 被推断为 string

TS 不允许您使用 string 类型作为 RawData['products'] 类型的索引。

如果你想向 TS 保证你能做到,你有两种方法:

1) 进行类型断言

  function demo(data: RawData) {
    for (const type in data.products) {
       // explicitly define type for `type` varable
      for (const product in data.products[type as keyof RawData['products']]) { // ok

      }
    }
  }

2) 使产品可编入索引

  interface Products {
    cars: Cars;
    bikes: Bikes;
    [prop: string]: Cars | Bikes
  }

更新

  interface Bikes {
    totals: Array<number>;
  }

  type Mix = { foo: 'a' };

  type Products = {
    cars: Cars;
    bikes: Bikes;
    mix?: Mix;
  }
  type Values<T> = T[keyof T]

  type MakeIndexed<T> = T & { [prop: string]: Values<T> }


  interface RawData {
    products: MakeIndexed<Products>
  }

  function demo(data: RawData) {
    for (const type in data.products) {
      for (const product in data.products[type]) { // ok

      }
    }
  }