never类型表示永不存在的值,常用于表示不会正常返回的函数或不可能发生的类型。
never 是所有类型的子类型,但没有类型是 never 的子类型(除了 never 本身)。
function throwError(message: string): never {
throw new Error(message)
}
throwError("出错了") // 后续代码不会执行
function infiniteLoop(): never {
while (true) {
// 永不退出
}
}
never 用于表示不可能的分支:
function process(value: string | number): void {
if (typeof value === "string") {
console.log(value.toUpperCase())
} else if (typeof value === "number") {
console.log(value.toFixed(2))
} else {
const _exhaustive: never = value // 确保所有情况都被处理
}
}
确保处理了所有可能的情况:
enum Color {
Red,
Green,
Blue
}
function getColorName(color: Color): string {
switch (color) {
case Color.Red:
return "红色"
case Color.Green:
return "绿色"
case Color.Blue:
return "蓝色"
default:
const _exhaustive: never = color
throw new Error(`未知的颜色: ${color}`)
}
}
如果添加新的枚举值,default 分支会报错:
enum Color {
Red,
Green,
Blue,
Yellow // 新增
}
// default 分支会报错:Type Color.Yellow is not assignable to type 'never'
TypeScript 会自动推断 never 类型:
function fail(message: string): never {
throw new Error(message)
}
function infinite(): never {
while (true) {}
}
// 变量推断
let value: string | number
if (typeof value === "string") {
// value: string
} else if (typeof value === "number") {
// value: number
} else {
// value: never
}
function assertNever(value: never): never {
throw new Error(`未处理的值: ${value}`)
}
type Shape = { kind: "circle"; radius: number } | { kind: "square"; size: number }
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2
case "square":
return shape.size ** 2
default:
return assertNever(shape)
}
}
function process(value: "a" | "b"): string {
if (value === "a") {
return "A"
}
if (value === "b") {
return "B"
}
// 这里 value 类型是 never
value // 永远不会执行
}
type Exclude<T, U> = T extends U ? never : T
type Result = Exclude<"a" | "b" | "c", "a"> // "b" | "c"
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
function fn(): string {
return "hello"
}
type FnReturn = ReturnType<typeof fn> // string
type StringAndNumber = string & number // never
let value: StringAndNumber // 永远无法赋值
| 类型 | 说明 |
|---|---|
| void | 函数正常结束,没有返回值 |
| never | 函数永不返回 |
function log(message: string): void {
console.log(message)
}
function fail(message: string): never {
throw new Error(message)
}
type NonNullable<T> = T extends null | undefined ? never : T
type Result = NonNullable<string | null | undefined> // string
// 过滤数组中的 null 和 undefined
function filterNonNull<T>(arr: (T | null | undefined)[]): T[] {
return arr.filter((item): item is T => item !== null && item !== undefined)
}
const items = [1, null, 2, undefined, 3]
const filtered = filterNonNull(items) // [1, 2, 3]
let n: never
n = 1 // 错误
n = "hello" // 错误
n = null // 错误
n = undefined // 错误
// 只有 never 可以赋值给 never
function fn(): never {
throw new Error("")
}
n = fn() // 正确
function fn() {
throw new Error("")
}
// 返回类型推断为 never
type Result = string | never // string
// never 在联合类型中会被忽略
type Result = string & never // never
// 任何类型与 never 交叉都是 never