TypeScript never 类型
本章介绍 TypeScript 的never类型,它们可以作为学习 TypeScript 类型系统的起点。
never 类型 #
为了保持与集合论的对应关系,以及类型运算的完整性,TypeScript 还引入了“空类型”的概念,即该类型为空,不包含任何值。
由于不存在任何属于“空类型”的值,所以该类型被称为never
,即不可能有这样的值。
let x:never;
上面示例中,变量x
的类型是never
,就不可能赋给它任何值,否则都会报错。
never
类型的使用场景,主要是在一些类型运算之中,保证类型运算的完整性,详见后面章节。另外,不可能返回值的函数,返回值的类型就可以写成never
,详见《函数》一章。
如果一个变量可能有多种类型(即联合类型),通常需要使用分支处理每一种类型。这时,处理所有可能的类型之后,剩余的情况就属于never
类型。
function fn(x:string|number) {
if (typeof x === 'string') {
// ...
} else if (typeof x === 'number') {
// ...
} else {
x; // never 类型
}
}
上面示例中,参数变量x
可能是字符串,也可能是数值,判断了这两种情况后,剩下的最后那个else
分支里面,x
就是never
类型了。
never
类型的一个重要特点是,可以赋值给任意其他类型。
function f():never {
throw new Error('Error');
}
let v1:number = f(); // 不报错
let v2:string = f(); // 不报错
let v3:boolean = f(); // 不报错
上面示例中,函数f()
会抛出错误,所以返回值类型可以写成never
,即不可能返回任何值。各种其他类型的变量都可以赋值为f()
的运行结果(never
类型)。
为什么never
类型可以赋值给任意其他类型呢?这也跟集合论有关,空集是任何集合的子集。TypeScript 就相应规定,任何类型都包含了never
类型。因此,never
类型是任何其他类型所共有的,TypeScript 把这种情况称为“底层类型”(bottom type)。
总之,TypeScript 有两个“顶层类型”(any
和unknown
),但是“底层类型”只有never
唯一一个。