这可能是因为我误解了枚举在Typescript中的工作方式,但我发现它非常不直观。
在我正在使用的库中,有一个具有完全相同签名的重载函数,唯一的区别是第一个签名使用enum类型的一个成员作为参数,而另一个使用另一个成员。
我似乎不能用枚举成员的并集调用这个函数。如果我使用枚举成员的数字字面值来调用函数,则没有问题。请看这里的简化示例:
Typescript playground link
declare enum ArgType {
FIRST = 1,
SECOND = 2
}
declare function create(name: string, options: ArgType.FIRST): number;
declare function create(name: string, options: ArgType.SECOND): number;
//^^^^ Above is library code
//Below is me trying to use it
create("asd", ArgType.FIRST); //works
create("asd", ArgType.SECOND); //works
create("asd", Math.random() < 0.5 ? 1 : 2); //works
create("asd", Math.random() < 0.5 ? ArgType.FIRST : ArgType.SECOND); //ERROR
let one = ArgType.FIRST;
let two = ArgType.SECOND;
create("asd", Math.random() < 0.5 ? one : 2); //works
create("asd", Math.random() < 0.5 ? 1 : two); //works
create("asd", Math.random() < 0.5 ? one : two); //ERROR
有人可以解释这里的行为,并告诉我如何可以有条件地调用这个创建函数与ArgType.FIRST
或ArgType.SECOND
,而无需在调用站点硬编码的数字?
错误行中的第二个参数
是:Math.random() < 0.5 ? ArgType.FIRST : ArgType.SECOND
Typescript类型为ArgType
。
ArgType
不是定义的create
函数重载的有效参数。
您可以通过将参数转换为Number
或使用as
:
create("asd", Number(Math.random() < 0.5 ? ArgType.FIRST : ArgType.SECOND));
create("asd", (Math.random() < 0.5 ? ArgType.FIRST : ArgType.SECOND) as number);
这将强制TS将形参解释为该enum的值。
如果您可以添加另一个重载,您可以添加以下内容,然后它将接受联合类型:
declare function create(name: string, options: ArgType.FIRST | ArgType.SECOND): number;
你也可以把它包装成一个自定义函数:
const wrappedCreate = (name: string, options: ArgType.FIRST | ArgType.SECOND) => {
return options === ArgType.FIRST ? create(name, options) : create(name, options)
}
wrappedCreate("asd", Math.random() < 0.5 ? ArgType.FIRST : ArgType.SECOND);
或者您可以使用类型转换而不是三元操作符
const wrappedCreate = (name: string, options: ArgType.FIRST | ArgType.SECOND) {
return create(name, options as ArgType.FIRST)
}