我是TypeScript的新手,感觉缺少了一些东西。
我想做的事:
- 我想创建一个对象
emptyEntry
,其中所有属性都是空列表,而不是一开始未定义 - 我知道我需要哪些属性,这些属性是数组
arr
的name
属性 - 最终,我希望能够将元素推送到
Entry
的属性 - 我希望尽可能严格,并以最佳方式使用Typescript
const emptyEntry = {
key1: [],
key2: []
}
const arr = [{
name: 'key1'
},
{
name: 'key2'
}
]
emptyEntry['key1'].push({
pushedItem: 'pushedItem1'
});
我尝试过的:
- 当设置为只读(
arrKey
(时,创建一个名为Entry
的类型,该类型具有基于arr
的键 - 创建一个接受列表参数的函数
createObject
,并首先创建一个带有动态键的空对象obj
。然后,它在列表参数上循环,并将新obj
的所有属性设置为空数组。它最终返回CCD_ 11作为CCD_ - 调用
createObject
并传入由arr
的名称值组成的名为keys
的映射变量 - 我现在可以将项目推送到键,因为它们已经作为空数组存在
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);
}
}
非常感谢您的任何建议!
创建一个具有key1
、key2
等作为自动包含成员的类是不起作用的,因为映射类型(用于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游乐场链接(