我在打字稿中有枚举,它们是用类型和对象实现的。我想要一个能够以类型安全的方式处理它们的通用方法。
type MyEnum = 1 | 2 ;
const MyEnum = {
AAA: 1 as MyEnum,
BBB: 2 as MyEnum,
}
type MyEnum2 = 'a' | 'b' ;
const MyEnum2 = {
a: 'a' as MyEnum2,
b: 'b' as MyEnum2,
}
明确这样做效果很好:
function getA<E extends 'myenum', B extends keyof typeof MyEnum>(e: E, key: B): void;
function getA<E extends 'myenum2', B extends keyof typeof MyEnum2>(e: E, key: B): void;
function getA<E, B>(e: E, key: B): void {
console.log(e, key);
}
getA("myenum", "AAA");
使用类型映射时,它不起作用:
type EnumTypes = {
myenum: MyEnum;
myenum2: MyEnum2;
}
function getB<E extends keyof EnumTypes, B extends keyof EnumTypes[E]>(e: E, key: B) {
console.log(e, key);
}
get4("myenum", "BBB");
为什么
keyof EnumTypes[E]
是 "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"
类型?
例如,如果
E
是 myenum
,则 EnumTypes[E]
是类型 MyEnum
。这与包含枚举值的 const MyEnum
完全无关,即使它们具有相同的名称。
要访问允许的枚举值,您可以创建另一个
const
映射:
const EnumTypes = {
myenum: MyEnum,
myenum2: MyEnum2,
}
function getB<E extends keyof typeof EnumTypes, B extends keyof typeof EnumTypes[E]>(e: E, key: B) {
console.log(e, key);
}
getB("myenum", "BBB");