根据Typescript中数组的值设置对象的键和默认值的最佳方法



我是TypeScript的新手,感觉缺少了一些东西。

我想做的事:

  • 我想创建一个对象emptyEntry,其中所有属性都是空列表,而不是一开始未定义
  • 我知道我需要哪些属性,这些属性是数组arrname属性
  • 最终,我希望能够将元素推送到Entry的属性
  • 我希望尽可能严格,并以最佳方式使用Typescript

const emptyEntry = {
key1: [],
key2: []
}
const arr = [{
name: 'key1'
},
{
name: 'key2'
}
]
emptyEntry['key1'].push({
pushedItem: 'pushedItem1'
});

我尝试过的:

  1. 当设置为只读(arrKey(时,创建一个名为Entry的类型,该类型具有基于arr的键
  2. 创建一个接受列表参数的函数createObject,并首先创建一个带有动态键的空对象obj。然后,它在列表参数上循环,并将新obj的所有属性设置为空数组。它最终返回CCD_ 11作为CCD_
  3. 调用createObject并传入由arr的名称值组成的名为keys的映射变量
  4. 我现在可以将项目推送到键,因为它们已经作为空数组存在

const arr = [{
name: 'key1'
}, {
name: 'key2'
}] as
const
type arrKey = typeof arr[number]['name'];
type Entry = {
[k in arrKey]: object[]
};
const createObject = (keys: string[]) => {
const obj: {
[k: string]: any
} = {};
keys.forEach(k => {
obj[k as keyof typeof obj] = [];
});
return obj as Entry;
};
const keys = arr.map(k => k.name);
const emptyEntry = createObject(keys);
emptyEntry.key1.push({
pushedItem: 'pushedItem1'
});

我想知道的是:

  • 我觉得我的方法不是很像TypeScript。有没有更好的方法来设置具有默认空数组值的Entry类型
  • 由于我将多次向数组推送项目,并且函数更复杂,我想知道是否可以建立一个类。我在这里遇到的问题是,类的构造函数应该基于arr设置键。如果可能的话,我不想手工设置。我试过这样的方法,但没能奏效

const arr = [{
name: 'key1'
}, {
name: 'key2'
}] as
const
const keys = arr.map(k => k.name);
class Entry {
constructor() {
keys.forEach(k => {
this[k] = [];
});
}
add(key: string, pushedItem: {}) {
this[key as keyof Entry].push(pushedItem);
}
}

非常感谢您的任何建议!

创建一个具有key1key2等作为自动包含成员的类是不起作用的,因为映射类型(用于Entry(与类不兼容。(一个类可以implements映射类型,但它必须显式地列出映射中的每个成员。(

在TypeScript方面,我看到的关键问题是数组的类型是object[],而不是更具体的类型。如果您提前知道这些数组中对象项的形状,那么一定要专门键入它们。如果不这样做,那么将它们键入为unknown[]并基于运行时测试进行强制转换可能更安全。

假设现在是unknown[],下面是您的代码版本,其中有一些内容经过了清理,使其更符合TypeScript习惯(使用Record实用程序类型和for...of,并且不接受密钥作为createObject的参数,因为它们应该只是arr中的密钥(:

const arr = [{
name: 'key1'
}, {
name: 'key2'
}] as const;
type arrKey = typeof arr[number]['name'];
type Entry = {
[k in arrKey]: unknown[]
};
const createObject = (): Entry => {
const obj: Record<string, unknown[]> = {};
for (const key of arr.map(k => k.name)) {
obj[key] = [];
}
return obj as Entry;
};
const emptyEntry = createObject();
emptyEntry.key1.push({
pushedItem: 'pushedItem1'
});

(TypeScript游乐场链接(

最新更新