bottom type
首先, never是一个bottom type,这如何体现呢?
注:✅表示
strictNullChecks 为false时的情况
never和unknown朝着两个相反的方向行进,所有的类型都可以赋值给unknown, never可以赋值给任何类型;unknown不能赋值给除any和自身之外的任何类型,除never本身外,任何类型都不能赋值给never
应用场景
-
用于从来不会返回值的函数
这可能有两种情况,一是函数中可能死循环
function loop():never { while(true) { console.log('I always does something and never ends.') } }另外一种情况就是这个函数总是会抛出一个错误,因此也总是没有返回值
function loop():never { throw new Error('error!') } -
穷尽检查(Exhaustiveness checking)
对于一个联合类型,将其类型收窄为
neverinterface Foo { type: 'foo' } interface Bar { type: 'bar' } type All = Foo | Barfunction handleValue(val: All) { switch (val.type) { case 'foo': // 这里 val 被收窄为 Foo break case 'bar': // val 在这里是 Bar break default: // val 在这里是 never const exhaustiveCheck: never = val break } }通过case 对可能的类型进行了相应处理,因此
default处val的类型是never,这也体现了never是一个底层类型:never只能赋值给never。如果之后联合类型All中添加了新的类型,但是在代码中忘记进行相应处理,那么就能提前暴露处错误,提醒开发者进行处理。never和void的区别
-
从赋值的角度来看,
undefined可以赋值给void类型的变量,除了never本身,任何值都不能赋值给never类型,也就是说never意味着没有任何值。注:strictNullChecks为
false时,null类型也是可以赋值给void的
-
void表示一个函数并不会返回任何值,当函数并没有任何返回值,或者返回不了明确的值的时候,就应该用这种类型。never表示一个函数从来不返回值,可能这个函数处于死循环,一直在运行,也可能这个函数运行过程中报错;never只能赋值给never,可以利用这个特性进行穷尽检查(Exhaustiveness checking) 。
-
注:
当基于上下文的推导,返回类型为
void时,不会强制返回函数一定不能返回内容,也就是说当这样一个类型(type vf = () => void)被应用时,也是可以返回值的,只不过返回的值会被忽略。type voidFunc = () => void; const f1: voidFunc = () => { return true; }; let a = f1() //let a: void const f2: voidFunc = () => true; let b = f2() //let b: void const f3: voidFunc = function () { return true; }; let c = f3() //let c: void可以看到
abc的类型都是void但当一个函数字面量定义返回一个
void类型,函数是一定不能返回任何东西的function f2(): void { return true; //Type 'true' is not assignable to type 'void'. } const f3 = function (): void { return true; //Type 'true' is not assignable to type 'void'. };