首页 > 解决方案 > 动态更改对象属性时的打字稿错误

问题描述

当我尝试基于动态变量更新对象的属性时遇到问题。我在 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
                        -------------
     ....
   }
}

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

我也尝试过使用:

export interface RawData {
    products: keyof Products
}

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

“字符串”类型不存在属性“自行车”。

标签: typescripttypes

解决方案


在您的情况下,变量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

      }
    }
  }

推荐阅读