打字稿 2 - 在三元/条件运算符表达式中抛出

Jør*_*edt 5 exception conditional-operator typescript

我尝试编译:

const value = "20"
const x : string | never = "10" === value ? throw Error("bad things") : "hello"
Run Code Online (Sandbox Code Playgroud)

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

为什么不能放入三元运算符的分支?或者是否有另一种有效的语法,也许是我缺少的编译选项?

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

Aka*_*gka 7

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

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

基于这个问题,直到 ECMA TC39 得出一些结论后才会开始实施。


Ale*_*lex 6

这就是多种语言的构造方式,有语句和表达式。在这种情况下,您正在分配x一个值,但抛出错误不是值/表达式,而是语句/操作。

你不能这样做,就像你不能写这样的东西一样:

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

这完全违反了语言的规则,即使你可以使用自我评估函数来“破解”它,理论上它会评估并且是一个表达式。

查看此问题以获得对语句和表达式的更好解释。

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

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

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

//...

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

const x: string = "hello";

//...
Run Code Online (Sandbox Code Playgroud)


Gre*_*Ros 6

这是该语言的语法怪癖。

该语句throw ex可以被视为具有类型 的表达式never,因为never是不返回的函数的类型,这正是当您throw. 在许多具有底部类型的语言中(技术术语是什么never——它不仅仅是一个“奇怪的关键字”)。

该语句throw ex与例如 语句不同,for (let x of ...)因为后者不能被理解为返回任何内容,而throw ex可以被理解为 return never