TypeScript 能否通过布尔逻辑推断出可区分联合"extracted"类型?



我越来越频繁地使用歧视结合(DU(,并开始喜欢它们。然而,我确实有一个问题似乎无法解决。如果为DU内联布尔检查,则可以依靠TypeScript(TS(自动推断类型。但是,如果提取布尔检查,TS就不能再局限于DU的特定子类型。我知道类型保护,但我想知道为什么编译器不支持提取的在线检查,特别是。

这是已知的限制吗?我应该提交bug/功能请求吗?

此处的示例(带TypeScript游乐场链接(:

type A = { type: "A"; foo: number };
type B = { type: "B"; bar: string };
type DU = A | B;
const checkIt = (it: DU) => {
const extractedCheck = it.type === "A";
if (extractedCheck) {
// it does not get narrowed
console.log(it.foo); // Error: Property 'foo' does not exist on type 'DU'.
}
if (it.type === "A") {
// but this is fine
console.log(it.foo);
}
};

更新TS4.4:

TypeScript 4.4将引入对将类型保护的结果保存到const的支持,如在microsoft/TypeScript#44730中实现的那样。此时,您的代码示例将正常工作:

const checkIt = (it: DU) => {
const extractedCheck = it.type === "A";
if (extractedCheck) {
console.log(it.foo); // okay
}
};

游乐场链接到代码


TS4.3及以下的答案:

在microsoft/TypeScript#12184上存在允许这样的类型保护结果为"0"的现有特征请求;保存";转换为稍后使用的命名值。该请求是公开的,但被列为";重新访问";因为没有明显的方法可以以性能化的方式实现它。该语言的首席架构师说:

这将需要我们跟踪一个变量的特定值对其他变量的影响,这将给控制流分析器增加大量复杂性(以及相关的性能损失(。尽管如此,我们还是会把它作为一个建议。

所以很遗憾,我不希望很快在该语言中看到这样的功能。


我的建议是继续使用内联类型检查。如果您有更复杂的类型保护情况,那么创建一个用户定义的类型保护函数可能是值得的,但我认为这对示例代码中的情况没有改进。


好的,希望能有所帮助;祝你好运

正如@jcalz所提到的,目前没有,但您可以始终应用一个最小的解决方法来解决这个问题。

诀窍是使extractCheck成为一个返回类型谓词的函数
(请参阅https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-定义类型的防护装置(

以下是一个工作示例:

type A = { type: "A"; foo: number };
type B = { type: "B"; bar: string };
type DU = A | B;
const checkIt = (it: DU) => {
// Make `extractCheck` a function 
const extractedCheck = (it: DU): it is A => it.type === "A";
if (extractedCheck(it)) {
console.log(it.foo);  // No error
}
};

最新更新