Typescript 2 - 在 ternary/conditional 运算符表达式中抛出

Typescript 2 - throw'ing in ternary/conditional operator expression

我尝试编译:

const value = "20"
const x : string | never = "10" === value ? throw Error("bad things") : "hello"

... 并在 throw - expression expected 上出现错误。我可以使用就地调用的内联方法解决此问题,但这看起来不太好。 ((() => {throw Error("bad things"})())

为什么不可以把三元运算符的分支扔进去?或者是否有另一种有效的语法,也许是我缺少的编译选项?

在变通方法中,如果函数体中没有大括号,Throw 似乎也不起作用,((() => throw Error("bad things")()).

这就是构造了多少种语言,你有语句和表达式。在这种情况下,您正在分配 x 一个值,但抛出错误不是 value/expression,而是 statement/operation.

你不能这样做的原因与你不能写类似的东西的原因相同:

const x : string | never = "10" === value ? for(var i in myArray) { /* do stuff */ } : "hello".

这完全违反了语言规则,即使您可以 "hack" 使用自求值函数绕过它,它在理论上求值并且是一个表达式。

查看 this question 以获得对语句和表达式的更好解释。

TS 中的never-关键字是一个奇怪的类型,与他们的控制流分析有关。它不允许您突然将语句视为表达式,因此如果您不想立即调用函数表达式,您可以只使用常规函数:

const value = "20"
var thrower = () => { throw Error("bad things"); }
const x: string | never = "10" === value ? thrower() : "hello";

如果这真的是你想要做的。这将更具可读性:

//...

if(value !== "10")
    throw Error("bad things");

const x: string = "hello";

//...

这是语言的语法怪癖。

语句 throw ex 可以被视为具有类型 never 的表达式,因为 never 是不属于 return 的函数类型,它当你 throw 时就会发生这种情况。在许多具有 bottom type 的语言中(never 的技术术语——它不仅仅是 "odd keyword")。

语句 throw ex 与语句 for (let x of ...) 不同,因为后者不能理解为 return 任何东西,而 throw ex 可以理解为return never.

这仍然是一个悬而未决的问题。

https://github.com/microsoft/TypeScript/issues/18535

基于此问题,在 ECMA TC39 得出一些结论之前不会开始实施。