在另一个函数中调用条件类型函数的Typescript



我试图做一个条件类型的函数,遇到这个stackoverflow问题,但不幸的是,它似乎不能很好地使用默认值(不管默认值在哪里),所以我遵循了那里的建议,使用过载代替。

事情似乎起作用了…直到我需要在包装器中调用该函数。下面是一个精简版:

// This works:
// Conditional type function with default value
// according to https://stackoverflow.com/questions/57057697
type UnionType="one"|"two"|"three";
// function check(t?:"one"):1; // Does not matter
function check(t:"one"):1;
function check(t:"two"):2;
function check(t:"three"):3;
function check(t:UnionType="one") {
if(t=="one"){
return 1;
}else if(t=="two"){
return 2;
}else if(t=="three"){
return 3;
}
return 1;
}
// This gives error:
// Calling that conditional type function within another function,
// using the same union type, but only one call
function check2(t:UnionType):1|2|3 {
return check(t);// <--- complain
}
// This works though:
// Calling that conditional type fucntion within another function,
// using multiply identical call (redundant type check)
function check3(t:UnionType):1|2|3 {
if(t=="one"){
return check(t);
}else if(t=="two"){
return check(t);
}else if(t=="three"){
return check(t);
}
return check(t);
}

打印稿操场

这段代码确实可以编译,但是你可以在操场上看到编译器抱怨check2()中的check(t)行不匹配任何过载,而在check3()中它没有问题,即使我们在这两个函数中做完全相同的事情,只是冗余的类型检查。

这个行为是有意的吗?什么是正确的方式做条件类型函数与默认值?

有一个不同的重复问题,我相信它回答了你的问题。

下面是引用自该线程的公认答案的核心问题:

将联合传递给重载Typescript不能"拆分";的在根据重载签名检查它之前。它是检查Promise | string类型的变量单独过载。并集不能赋值给其成员,因此没有接受Promise的重载签名|字符串。

这是一个已知的行为和一些关于这个日期的GitHub问题年。

本质上,typescript不能像你期望的那样比较你的UnionType和每个重载。它在最后一个函数中起作用,因为您用冗余值检查保护了类型,从而告诉typescript,在进入check(t)之前,t只会是那些特定的值,因为存在重载。

当你做check(t:UnionType)没有那些多余的检查,它不会工作,因为它比较"one"|"two"|"three""one",然后与"two",然后与"three"。这些比较不相等,因此它失败了。

相关内容

  • 没有找到相关文章

最新更新