从Typescript中对象数组的属性中提取键/值对象类型



我有一个使用相同属性的对象的常量数组。类似这样的东西:

const allData = [{
name: 'info', content: Info
},{
name: 'other', content: Other
},{
...
}];

现在,我想创建一个变量,在运行其他代码后,将这些代码映射到一个对象中,其中键是name属性的字符串,值是content特性的实例。考虑到这一点,我想知道如何在Typescript中定义这样一个类型,它基本上会从我的常量中提取这些属性,这样它最终会变成这样:

Type ContentInstances = {
info: Info,
other: Other 
...
}

是否有这样一种方法可以在Typescript上使用typeof和其他东西来基于allData常量动态实现这一点?

编辑基本上在稍后阶段,我会有这样的东西:

let myVar: ContentInstances;
...
myVar = allData.reduce((obj, value) => {
obj[value.name] = new value.content(customParam);
return obj;
}, {})

以下应该可以做到:

const allData = [
{
name: "info",
content: { hey: "you" },
},
{
name: "other",
content: { bro: "chill" },
},
] as const;
type ContentInstances = {
[K in typeof allData[number]["name"]]: Extract<
typeof allData[number],
{ name: K }
>["content"];
};
declare const foo: ContentInstances;
foo.info.hey;
foo.other.bro;

类型ContentInstances遍历包含在allData中的对象的所有"name"键。它将每个键映射到具有该键的对象的并集中,然后使用"content"键对并集进行索引。

您需要首先使用as const键入常量变量,以允许TypeScript对文本类型进行智能推理。之后,您可以将其与映射的类型结合起来创建一个新类型。

const allData = [{
name: 'info', content: { hey: "you" }
}, {
name: 'other', content: { bro: "chill" }
}] as const;
// the intersection lets us pick out the types in the array that match
// the given `name` property type
type ContentInstances =
{ [K in typeof allData[number]["name"]]: typeof allData[number] & { readonly name: K } }
const foo: ContentInstances["info"] = {
name: "info",
content: {
hey: "you",
// @ts-expect-error this correctly fails
asdf: 2,
}
};

TypeScript游乐场链接

最新更新