我有一种情况,我想将一个枚举映射到一个类型,以便用户可以调用一个函数,并基于传递给第一个参数的枚举,可以推断出第二个参数的类型。
我将其设置如下:
enum MyEnum {
One,
Two
}
interface OnePayload {
one: string;
}
interface TwoPayload {
two: string;
}
type FuncPayload<T> = T extends MyEnum.One
? OnePayload
: T extends MyEnum.Two
? TwoPayload
: any;
const func = <T extends MyEnum>(key: T, payload?: FuncPayload<T>) => {
return payload;
};
可用于以下用途:
func(MyEnum.One,{one: 'a'}); // OK
func(MyEnum.Two,{one: 'a'}); // Throws type error
func(MyEnum.Two,{two: 'a'}); // OK
这很好用,除了在我的示例中,我有100〜个枚举值要映射到它们各自的类型。一旦我在FuncPayload
类型中添加了许多条件,每当我使用该类型时,它都会引发Type instantiation is excessively deep and possibly infinite.
错误。
有没有一种更好的方法来实现这一目标?或b)使用此方法解决此错误的方法?
答案 0 :(得分:0)
您是否考虑过改用Union Types和Type Guards,这样就不需要实际传递枚举类型了?
interface PayloadA {
one: string;
}
interface PayloadB {
two: string;
}
function isPayloadA(object: PayloadA | PayloadB): object is PayloadA {
return (object as PayloadA).one !== undefined;
}
function myOperation(payload: (PayloadA|PayloadB)) {
if (isPayloadA(payload)) {
// payload is now strongly typed as PayloadA
}
}
我想这最终取决于您要完成的工作。您的func
函数应该做什么?强力投射松散类型的对象?
答案 1 :(得分:0)
找到了行之有效的东西:
enum MyEnum {
One,
Two
}
interface OnePayload {
one: string;
}
interface TwoPayload {
two: string;
}
interface FuncPayloadMap {
[MyEnum.One]: OnePayload;
[MyEnum.Two]: TwoPayload;
}
const func = <T extends MyEnum>(key: T, payload?: FuncPayloadMap[T]) => {
return payload;
};
我想您可以使用接口将每个枚举值映射到接口,然后只使用泛型类型在映射中引用正确的接口。