开发者问题收集

如何使用 TypeScript 声明空对象数组的类型?

2020-09-24
2842

假设数组为 const items = [{category:'cat1', name:'name1'},{category:'cat2', name:'name2'}]

我想将上述数组构造为如下所示的对象格式:

{
  'cat1':'name1',
  'cat2':'name2'
}

如果没有 typescript,我可以执行以下操作来解决问题:

const parseFunction = (items) => {
 const newObj = {};
 for (const item of items) {
   newObj[item.category] = newObj[item.name];
 }
 return newObj;
}

但是使用下面的 typescript:

interface IItems{
 category: string,
 name: string
}

interface INewObj{
 'cat1': string,
 'cat2': string
}

const parseFunction = (items: IItems[]) => {
 const newObj = {} as INewObj;
 for (const item of items) {
   newObj[item.category] = newObj[item.name];
 }
 return newObj;
}

newObj[item.category] ​​= newObj[item.name] 引发以下 TS 错误

Element implicitly has an 'any' type because expression of type 'number' can't be used to index type 'IQuotaByCategory'.
No index signature with a parameter of type 'number' was found on type 'IQuotaByCategory'.ts(7053)

我应该如何解决这个问题?

2个回答

此解决方案能满足您的需求吗?

使用 Record<Keys, Type> 映射未知的键和值。

Typescript 代码

const items: IItems[] = [{ category: 'cat1', name: 'name1' }, { category: 'cat2', name: 'name2' }];

interface IItems {
    category: string,
    name: string
}

type NewObjType = Record<string, string>;

const parseFunction = (items: IItems[]): NewObj => {
    const newObj: NewObjType = {};

    for (const item of items) {
        newObj[item.category] = item.name;
    }

    return newObj;
}

console.log(parseFunction(items));

Javascript 代码片段

"use strict";
const items = [{ category: 'cat1', name: 'name1' }, { category: 'cat2', name: 'name2' }];
const parseFunction = (items) => {
    const newObj = {};
    for (const item of items) {
        newObj[item.category] = item.name;
    }
    return newObj;
};
console.log(parseFunction(items));

PS:您在这里犯了一个小错误 newObj[item.category] ​​= newObj[item.name] ,因为该值在 newObj 变量中尚不存在。我已更改为正确的赋值,如下所示: newObj[item.category] ​​= item.name

Carlo Corradini
2020-09-24

实际上,我猜您不会真正知道类别是 cat1cat2 等,您只知道它们是字符串。因此, INewObj 的定义需要更宽松一些。

type INewObj = {
  [key: string]: string
}

可以进一步缩短为 Record<string, string>

游乐场链接

您可以更进一步,通过允许 Typescript 为您推断来完全消除 INewObj

游乐场 2

jlouzado
2020-09-24