我有下一个数组
const arrayData = ['a', 'b'] as const;
这个数组有下一个类型 ArrayType = ('a' | 'b')[];
我想获取与下一个类型一致的对象:
type Type = {
a: boolean,
b: boolean,
}
预期对象
const result : Type = {
a: false,
b: false,
}
我想将 arrayData
转换为 result
const result: Type = arrayData.reduce((r, key) => {
return {
...r,
key: false,
}
}, {});
但此代码没有有效类型
答案 0 :(得分:1)
你的第一个假设是错误的:
const foo = ['a', 'b'] as const; // Type is ['a', 'b'], a tuple of literals
const bar = ['a', 'b']; // Type is ('a' | 'b')[], a list of a union of literals
使用 ['a', 'b']
而不管 const
您可以这样输入:
type ObjectFromList<T extends ReadonlyArray<string>, V = string> = {
[K in (T extends ReadonlyArray<infer U> ? U : never)]: V
};
说明:
T extends ReadonlyArray<string>
需要一个类型参数,它是一个数组,其元素可以变成字符串,只读允许您使用 const
。每个字符串文字类型都可以传递到字符串中。T extends ReadonlyArray<infer U> ? U : never
是一个条件,意思是:“如果 T 是一个数组,则获取其元素的类型(U
),否则没有类型”。:
之后设置 never 意味着我们知道它永远不会发生。
infer U
将推断 T 可能的最小类型集,在您的情况下是字符串文字的并集 ('a' | 'b'
)[K in ...]: V
使用数组元素中所有可能的值作为指向 V
类型值的键(我们将默认值设置为 string
,但您可以传递另一个).最后,关于reduce。您需要在迭代期间设置您正在使用的类型:
const result: Type = arrayData.reduce((r, key) => {
return {
...r,
[key]: false,
}
}, {} as Type); // Here
要精确地限制类型,您需要通过键入初始累加器和函数的返回来键入reduce:
const result: Type = arrayData.reduce((r, key): Type /* HERE */ => {
return {
...r,
[key]: false,
}
}, {} as Type);
答案 1 :(得分:0)
我在您的示例中发现了 2 个问题:
对象的动态键应该在方括号内:(key:
应该是 [key]:
您可以在 TypeScript 中通过 reduce
运算符定义初始 as
累加器的类型。
const arrayData = ['a', 'b'] as const;
type Type = {
a: boolean,
b: boolean,
}
const result: Type = arrayData.reduce((r, key: string) => {
return {
...r,
[key]: false,
}
}, {} as Type);