打字稿中 Record 的通用初始值设定项
Generic initializer for Record in typescript
我正在尝试编写一个初始化 Record<X,Y>
in typescript
的函数
我的问题是我遇到了错误
X 仅指类型,但在此处用作值。
在我的情况下,X 将始终是一个 enum
,但我也不知道如何在签名中对其进行精确描述
这是我写的函数:
function initiateRecord<X extends string | number,Y>(enumX: typeof X, defaultValue: Y): Record<X,Y>{
const toReturn = {} as Record<X,Y>;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
要测试的完整代码:
enum EnumA {
A = 'A',
B = 'B',
C = 'C',
}
function initiateRecord<X extends string | number,Y>(enumX: typeof X, defaultValue: Y): Record<X,Y>{
const toReturn = {} as Record<X,Y>;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
class AA {
bb: Record<EnumA, boolean> = initiateRecord(EnumA, false);
constructor(){
}
}
const test = new AA();
test.bb[EnumA.A] = true;
alert(JSON.stringify(test));
请注意,当我点击 运行 时,它似乎工作正常,但那个错误困扰着我,我无法像那样将它添加到我的项目中。
你的几个类型有点不对。枚举的类型更接近于 {}
或 {[index: string]: any}
您的 return 类型会略有不同,实际上会是 Record<string,Y>
enum EnumA {
A = 'A',
B = 'B',
C = 'C',
}
function initiateRecord<Y>(enumX: {[index: string]: any}, defaultValue: Y): Record<string,Y>{
const toReturn:Record<string,Y> = {} ;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
class AA {
bb: Record<EnumA, boolean> = initiateRecord(EnumA, false);
constructor(){
}
}
const test = new AA();
test.bb[EnumA.A] = true;
alert(JSON.stringify(test));
可以使用 Object.assign
实现更简洁的(1 行)语法,即
function initiateRecord<Y>(enumX: {[index: string]: any}, defaultValue: Y): Record<string,Y>{
return Object.assign({},...Object.keys(enumX).map(x=>({[x]:defaultValue})))
}
但是我会质疑您的方法 - 如果您的枚举值将被立即覆盖,它们有什么优点?
我正在尝试编写一个初始化 Record<X,Y>
in typescript
我的问题是我遇到了错误
X 仅指类型,但在此处用作值。
在我的情况下,X 将始终是一个 enum
,但我也不知道如何在签名中对其进行精确描述
这是我写的函数:
function initiateRecord<X extends string | number,Y>(enumX: typeof X, defaultValue: Y): Record<X,Y>{
const toReturn = {} as Record<X,Y>;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
要测试的完整代码:
enum EnumA {
A = 'A',
B = 'B',
C = 'C',
}
function initiateRecord<X extends string | number,Y>(enumX: typeof X, defaultValue: Y): Record<X,Y>{
const toReturn = {} as Record<X,Y>;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
class AA {
bb: Record<EnumA, boolean> = initiateRecord(EnumA, false);
constructor(){
}
}
const test = new AA();
test.bb[EnumA.A] = true;
alert(JSON.stringify(test));
请注意,当我点击 运行 时,它似乎工作正常,但那个错误困扰着我,我无法像那样将它添加到我的项目中。
你的几个类型有点不对。枚举的类型更接近于 {}
或 {[index: string]: any}
您的 return 类型会略有不同,实际上会是 Record<string,Y>
enum EnumA {
A = 'A',
B = 'B',
C = 'C',
}
function initiateRecord<Y>(enumX: {[index: string]: any}, defaultValue: Y): Record<string,Y>{
const toReturn:Record<string,Y> = {} ;
Object.keys(enumX).forEach(key => {
toReturn[key] = defaultValue;
});
return toReturn;
}
class AA {
bb: Record<EnumA, boolean> = initiateRecord(EnumA, false);
constructor(){
}
}
const test = new AA();
test.bb[EnumA.A] = true;
alert(JSON.stringify(test));
可以使用 Object.assign
实现更简洁的(1 行)语法,即
function initiateRecord<Y>(enumX: {[index: string]: any}, defaultValue: Y): Record<string,Y>{
return Object.assign({},...Object.keys(enumX).map(x=>({[x]:defaultValue})))
}
但是我会质疑您的方法 - 如果您的枚举值将被立即覆盖,它们有什么优点?