当前位置: 首页 > 科技观察

理解TypeScript的Never类型

时间:2023-03-19 22:44:20 科技观察

今天我们将深入探讨never类型,并介绍大家可能遇到的情况。1、never的特点TypeScript使用never关键字来表示逻辑上不应该发生的情况和控制流程。在实践中,我们在工作中并不经常遇到never的使用,但仍然有必要了解它如何为TypeScript的类型安全做出贡献。官方文档是这样描述never的:never类型是任意类型的子类型,也可以赋值给任意类型;但是,没有类型是never的子类型,也不能分配给never类型(除了never本身)。也就是说,一个never类型的变量不能赋值给任何其他变量,但没有其他变量可以赋值给never。让我们看一个例子:constthrowErrorFunc=()=>{thrownewError("error")};letneverVar:never=throwErrorFunc()constmyString=""constmyInt:number=neverVar;neverVar=myString//Type'string'isnotassignabletotype'never'我们可以暂时忽略throwErrorFunc的作用,只知道它可以初始化never类型的变量。从上面的代码可以看出,never类型的变量neverVar可以赋值给number类型的变量myInt。但是string类型的myString变量不能赋值给neverVar,赋值会报错。这就是我上面说的,你不能将任何其他类型的变量赋值给never,即使是any类型的变量。2.函数中的neverTypeScript使用never作为端点无法到达的函数的返回类型。主要有两种情况:函数抛出错误异常。函数包含一个无限循环。查看上面提到的throwErrorFunc函数,TypeScript会推断该函数的返回类型永远不会:constthrowErrorFunc=()=>{thrownewError("error")};另一种情况是,如果其中一个始终为true表达式会产生一个无限循环,该循环没有break或return语句。TypeScript会推断此函数的返回类型永远不会:constoutput=()=>{while(true){console.log("loop");}};3.never和void的区别那么什么是void类型呢??为什么当我们有void时我们永远不需要打字?never和void之间的主要区别在于void类型的值可以是未定义的或null。TypeScript对不返回任何内容的函数使用void。如果没有为函数指定返回类型,并且代码中没有返回任何内容,TypeScript将推断其返回类型为void。在TypeScript中,不返回任何内容的void函数实际上返回undefined。让我们看一个例子:constfunctionWithVoidReturnType=()=>{};console.log(functionWithVoidReturnType());//undefined在这里,TypeScript将推断此函数的返回类型为void。我们通常会忽略void函数的返回值。这里注意:根据never类型的特点,我们不能将void赋值给never:constmyVoidFunction=()=>{}neverVar=myVoidFunction()//ERROR:Type'never'isnotassignabletotype'void'4.never作为可变类型一个变量可能是never类型,如果它的范围由一个类型保护,而该类型由一个永远不会为真的类型保护。通常,这表明条件逻辑存在缺陷。考虑以下示例:constunExpectedResult=(myParam:"this"|"that")=>{if(myParam==="this"){}elseif(myParam==="that"){}else{console.log({myParam})}}在这个例子中,当函数执行到console.log({myParam})时,myParam的类型将是never。这是因为我们将myParam的类型设置为这个或那个。由于TypeScript将类型myParam视为两种类型之一,因此从逻辑上讲,第三个else语句永远不应该出现。所以TypeScript会将参数类型设置为never。5.详尽检查在实践中never可能用不到的一个地方是详尽检查。这有助于确保我们处理代码中的每个边缘情况。以下是如何使用详尽检查为switch语句添加更好的类型安全性:typeAnimal="cat"|“狗”|"bird"constshouldNotHappen=(animal:never)=>{thrownewError("error")}constmyPicker=(pet:Animal)=>{switch(pet){case"cat":{//...return}case"dog":{//...return}}returnshouldNotHappen(pet)}添加"returnshouldNotHappen(pet)"时,你会看到一条错误信息:这里的错误信息告诉我们忘记包含它在switch语句中。这是获得编译时安全并确保处理switch语句中的所有情况的简洁模式。6.结论如您所见,TypeScript中的never类型在某些情况下很有用。在大多数情况下,从不表示代码中存在错误。但在某些情况下,例如详尽检查,它可以成为帮助编写更安全的TypeScript代码的好工具。