Rem*_*sen 19 types type-inference typescript
有人可以解释一下为什么给出以下代码:
let f = () => {
throw new Error("Should never get here");
}
let g = function() {
throw new Error("Should never get here");
}
function h() {
throw new Error("Should never get here");
}
Run Code Online (Sandbox Code Playgroud)
推断出以下类型:
f
是 () => never
g
是 () => never
h
是 () => void
我期望的类型h
是() => never
为好.
谢谢!
Rya*_*ugh 27
好问题.不同的是,f
和g
有功能的表达,在那里h
是一个函数声明.当一个函数是throw
-only时,never
如果它是一个表达式,它将获得类型,void
如果它是一个声明.
当然上面的段落实际上没有帮助.为什么函数表达式和函数声明之间的行为存在差异?让我们看看每种情况下的一些反例.
void
考虑一些代码:
function iif(value: boolean, whenTrue: () => number, whenFalse: () => number): number {
return value ? whenTrue() : whenFalse();
}
let x = iif(2 > 3,
() => { throw new Error("haven't implemented backwards-day logic yet"); },
() => 14);
Run Code Online (Sandbox Code Playgroud)
这段代码好吗?它应该是!throw
当我们认为不应该调用函数时,或者只应在错误情况下调用函数时,编写ing函数是很常见的.但是,如果函数表达式的类型是void
,则iif
拒绝调用.
所以从这个例子中可以清楚地知道,函数表达式只throw
应该返回never
,而不是void
.实际上这应该是我们的默认假设,因为这些函数符合never
(在正确类型的程序中,never
无法观察到类型的值)的定义.
never
在阅读完前一节之后,你应该说"好了,为什么不把所有的投掷功能都归还never
呢?"
简短的回答是,事实证明这是一个重大改变.那里有很多代码(特别是在abstract
关键字之前的代码),看起来像这样
class Base {
overrideMe() {
throw new Error("You forgot to override me!");
}
}
class Derived extends Base {
overrideMe() {
// Code that actually returns here
}
}
Run Code Online (Sandbox Code Playgroud)
但是返回的函数void
不能替代返回的函数never
(记住,在正确类型的程序中,never
无法观察到值),因此Base#overrideMe
返回会never
阻止Derived
提供never
该方法的任何非实现.
通常,虽然总是抛出的函数表达式经常作为占位符存在,但总是抛出的Debug.fail
函数声明非常罕见.表达式经常被别名或忽略,而声明是静态的.函数的声明说throw
今天的工作实际上是有可能做一些有用的事情明天; 在没有返回类型注释的情况下,提供更安全的东西void
(即不要查看此返回类型)而不是never
(即此函数是一个黑洞,将占用当前执行堆栈).
归档时间: |
|
查看次数: |
909 次 |
最近记录: |