bottom type
首先, never
是一个bottom type
,这如何体现呢?
注:✅表示 strictNullChecks
为false时的情况
never
和unknown
朝着两个相反的方向行进,所有的类型都可以赋值给unknown
, never
可以赋值给任何类型;unknown
不能赋值给除any和自身之外的任何类型,除never
本身外,任何类型都不能赋值给never
应用场景
用于从来不会返回值的函数
这可能有两种情况,一是函数中可能死循环
1
2
3
4
5function loop():never {
while(true) {
console.log('I always does something and never ends.')
}
}另外一种情况就是这个函数总是会抛出一个错误,因此也总是没有返回值
1
2
3function loop():never {
throw new Error('error!')
}穷尽检查(Exhaustiveness checking)
对于一个联合类型,将其类型收窄为
never
1
2
3
4
5
6
7interface Foo {
type: 'foo'
}
interface Bar {
type: 'bar'
}
type All = Foo | Bar1
2
3
4
5
6
7
8
9
10
11
12
13
14function 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)
被应用时,也是可以返回值的,只不过返回的值会被忽略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 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可以看到
a
b
c
的类型都是void
但当一个函数字面量定义返回一个
void
类型,函数是一定不能返回任何东西的
1
2
3
4
5
6
7 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'.
};