条件表达式会产生奇怪的行为.

示例:

const value = false
const result = value ? 1 : 2  // <--   result is 1 | 2, not 2

我的问题是,为什么在TypeScrip中条件表达式类型总是求值为两者的并集

推荐答案

这种行为被认为是故意的,正如在microsoft/TypeScript#14206中提到的那样.在microsoft/TypeScript#39995microsoft/TypeScript#43040中,改变这类行为的相关建议目前被标记为"等待更多反馈",这意味着如果你足够关心这个改变,你可能想要go 描述你的用例,为什么它是令人信服的,为什么现有的变通方法不够充分.我认为这不会有太大影响,但可能不会.


为了使false ? 1 : 2被认为是类型2,编译器需要对conditional/ternary operator表达式内部的可达性执行control flow analysis.

不执行这样的分析,因此编译器假设条件表达式的两个分支都是可到达的,因此表达式的类型始终是每个表达式中的union个类型.

对条件statements执行控制流分析,尽管您得到的是可达性错误,而不是缩小范围:

function foo() { // still returns 1 | 2, but:
    if (false) {
        return 1; // error! Unreachable code detected!
    } else {
        return 2;
    }
}

但同样,这不会发生在条件表达式中.你的问题是:为什么?


您希望在这里看到的控制流分析并不是免费的;它会对代码库中的每个条件表达式施加一定程度的性能损失.因此,问题是:人们多久编写一次x ? y : z形式的真实世界代码,其中x在编译时已知为truthyfalsy,添加额外的分析是否足够频繁?

在微软/TypeScrip#39995中,TS团队成员says

一些用例不仅仅是没有人会合理编写的代码(例如,true ? x : y或其类似功能),这将是很好的动机.对knowntruefalse的值进行运算的情况相对较少.

因此,权威的答案似乎是,TS团队认为这种代码既不常见也不合理,因此不值得添加额外的控制流分析来处理它.


同样,如果您有不同的感觉并希望看到这种更改,您可能希望转到相关的GitHub问题并解释原因,包括一个令人信服的理由,说明为什么有人可能合理地编写这样的代码,特别是如果您可以找到现有代码库的示例,这些代码足够使用这些代码,值得增加编译时间.但我再说一次,我不会让你对看到这一点真正改变抱有太大希望,因为有很多长期开放的功能请求,比那些具有更多的社区参与.哦,好吧.至少现在你知道为什么会是这样了.

Playground link to code

Typescript相关问答推荐

使用类和子类以及迭代类属约束对类属递数据 struct 建模

为什么文字必须硬编码才能在TypScript中工作?

为什么TypScript对条件函数类型和仅具有条件返回类型的相同函数类型的处理方式不同?

如何将@for的结果绑定到变量?

如何在TypeScript中将一个元组映射(转换)到另一个元组?

ANGLE找不到辅助‘路由出口’的路由路径

Express Yup显示所有字段的所有错误

如何重构长联合类型?

通过字符串索引访问对象';S的值时出现文字脚本错误

嵌套对象的类型

如何实现异构数组内函数的类型缩小

如何在NX工作区项目.json中设置类似angular.json的两个项目构建配置?

如何创建一家Reduxstore ?

棱角分明-什么是...接口类型<;T>;扩展函数{new(...args:any[]):t;}...卑鄙?

具有匹配功能的TS通用事件处理程序

如何从上传文件中删除预览文件图标?

两个名称不同的相同打字界面-如何使其干燥/避免重复?

TS不能自己推断函数返回类型

获取类属性的类型';TypeScript中的getter/setter

在tabel管理区域react js上设置特定顺序