2

我正在尝试修剪从 REST API 返回的对象数组中的值。

这是interface我期待的对象。

interface IProduct {
  productId: number;
  qty: number;
  code: string;
  customer: string;
  description: string;
}

我正在尝试遍历对象数组并修剪对象的所有值。

products.forEach(record => {
  if (record) {
    Object.keys(record).map(key => {
      record[key] = record[key].trim();
    });
  }
});

我收到以下错误。

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IProduct'.
No index signature with a parameter of type 'string' was found on type 'IProduct'.

我尝试向对象添加索引签名,但没有运气。[key: string]: string还有key: {[index: string]: string}

有什么我遗漏的吗,我认为这足以让 TS 编译器停止抱怨。

这是对象的参考。

const products: Product[] = [
  {
    productId: 1,
    qty: 100,
    code: 'code',
    customer: 'customer',
    description: 'the description',
  },
  {
    productId: 2,
    qty: 102,
    code: 'code',
    customer: 'customer',
    description: 'the description',
  },
];

非常感谢

4

1 回答 1

2

的定义Object.keys是:

interface ObjectConstructor {
  keys(o: object): string[];
  keys(o: {}): string[];
}

这是因为您可以编写如下代码:

const object = {
  productId: 1,
  qty: 100,
  code: 'code',
  customer: 'customer',
  description: 'the description',
  someOtherKey: 'foo', // extra key here
};
const product: IProduct = object;
const keys = Object.keys(product); // keys contains someOtherKey

要修复您的错误,您可以使用类型断言:

products.forEach(record => {
  if (record) {
    (Object.keys(record) as (keyof IProduct)[]).map(/* ... */);
  }
});

但是,如果你知道不会有额外的键,你可以添加这个重载:

declare global {
  interface ObjectConstructor {
    keys<K extends PropertyKey>(o: Record<K, unknown>): K[];
  }
}
// declare global can only be in a module, so if the file isn't
// a module already you'll need to add this
export {};

这样,您将不需要类型断言,但这在技术上不是类型安全的。

于 2020-12-05T04:51:13.803 回答