在查看TypeScript 2.0中的新功能时,我发现了never
类型。根据文档,它似乎是一种设置永不返回的函数类型的聪明方法。
现在,如果我正确阅读了所有内容,那么never
可以分配给每种类型,但只有never
可以分配给never
。因此,在VS Code中编写一个小测试时,我最终得到了以下结论:
function generateError(){
throw new Error("oops");
}
function do(option: "opt1" | "opt2"){
if(option === "opt1") return true;
if(option === "opt2 ) return false;
generateError();
}
let res = do("blah");
嗯,res
的预期类型是什么?根据编译器,它是string | undefined
(这是有道理的,尽管我必须说我期望string
)。我想我没有看到有一种新类型只是为了表示永不返回的函数。我们真的需要这个概念吗?这只是一个有助于它有更好的流量分析的编译器吗?
答案 0 :(得分:4)
您可以使用never
确保您不会错过任何合同。
function forever(): never {
while (true) {
break; // Error because you can't leave the function.
}
}
enum Values {
A,
B
}
function choose(value: Values) {
switch (value) {
case Values.A: return "A";
}
let x: never = value; // Error because B is not a case in switch.
}
答案 1 :(得分:3)
从来没有信息表明此特定部分不可访问。例如,这段代码
function do(): never {
while (true) {}
}
您有一个无限循环,我们不想迭代无限循环。就这么简单。
但是一个真正的问题是,它对我们有什么用? 例如,在创建更多高级类型以指向不是
时可能会有所帮助例如,让我们声明我们自己的NonNullable类型:
type NonNullable<T> = T extends null | undefined ? never : T;
在这里,我们正在检查T是否为null或未定义。如果是这样,那么我们指出它永远都不会发生。然后在使用此类型时:
let value: NonNullable<string>;
value = "Test";
value = null; // error
答案 2 :(得分:1)
从不(永远)返回的函数和可能抛出的函数并不完全相同。
例如:
function foo(option: "opt1" | "opt2"): string | undefined {
if (option === "opt1") return true;
if (option === "opt2") return false;
throw new Error("unknown option");
}
function bar(option: "opt1" | "opt2"): never {
while (true) {
doOption(option);
}
}
第一个可能(或可能不)返回,但它可以,因此返回类型不能是never
。如果它可以返回值,则返回类型显然不是never
。
第二个永远不会回来。不是价值,不是未定义,没有。它不会返回,因此类型可以是never
。
有些功能看起来像#2,但实际上属于#1,通常在涉及throw
时或者您在节点中使用process.exit
时(这可能是&#t;}返回,因为它杀死了这个过程。)