理解TypeScript 2中的never类型

问题描述 投票:2回答:3

在看看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)。我想我没有看到有一个新类型只是为了表示永不返回的函数。我们真的需要这个概念吗?这只是一个编译器,有助于它有更好的流量分析?

typescript typescript2.0
3个回答
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

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
投票

永远(永远)返回的函数和可能抛出的函数并不完全相同。

例如:

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时(因为它杀死了进程而无法返回)。

© www.soinside.com 2019 - 2024. All rights reserved.