TypeScript void与never #

一、void类型 #

1.1 什么是void #

void类型表示没有任何类型,通常用于表示函数没有返回值。

typescript
function log(message: string): void {
    console.log(message);
}

log('Hello, TypeScript!');

1.2 void的特点 #

  • 表示没有返回值
  • 只能赋值undefinednull(非严格模式)
  • 常用于函数返回类型
typescript
let unusable: void = undefined;

function doNothing(): void {
    return;
}

1.3 void的使用场景 #

没有返回值的函数 #

typescript
function greet(name: string): void {
    console.log(`Hello, ${name}!`);
}

function logError(error: string): void {
    console.error(error);
}

function setTimeout(callback: () => void, ms: number): void {
    setTimeout(callback, ms);
}

回调函数 #

typescript
type Callback = () => void;

function executeCallback(callback: Callback): void {
    callback();
}

executeCallback(() => {
    console.log('Callback executed');
});

事件处理器 #

typescript
interface EventHandler {
    (event: Event): void;
}

function addClickListener(handler: EventHandler): void {
    document.addEventListener('click', handler);
}

1.4 void vs undefined #

typescript
function returnVoid(): void {
    return;
}

function returnUndefined(): undefined {
    return undefined;
}

let v1: void = returnVoid();
let v2: undefined = returnUndefined();

1.5 void的返回值 #

typescript
function fn(): void {
    return undefined;
}

function fn2(): void {
    return null;
}

二、never类型 #

2.1 什么是never #

never类型表示永远不会发生的类型。它用于表示永远不会返回的函数或不可能存在的值。

typescript
function error(message: string): never {
    throw new Error(message);
}

function infiniteLoop(): never {
    while (true) {}
}

2.2 never的特点 #

  • 是所有类型的子类型
  • 没有任何类型是never的子类型
  • 不能赋值任何值给never
  • 用于永不返回的函数
typescript
let n: never;

n = 'hello';
n = 123;
n = null;

2.3 never的使用场景 #

抛出异常的函数 #

typescript
function throwError(message: string): never {
    throw new Error(message);
}

function fail(): never {
    return throwError('Something went wrong');
}

无限循环 #

typescript
function infiniteLoop(): never {
    while (true) {
        console.log('Running...');
    }
}

类型收窄的穷尽检查 #

typescript
type Shape = 'circle' | 'square' | 'triangle';

function getArea(shape: Shape): number {
    switch (shape) {
        case 'circle':
            return Math.PI;
        case 'square':
            return 1;
        case 'triangle':
            return 0.5;
        default:
            const _exhaustiveCheck: never = shape;
            return _exhaustiveCheck;
    }
}

不可能的交叉类型 #

typescript
type StringAndNumber = string & number;

let value: StringAndNumber;

2.4 never与函数重载 #

typescript
function fn(x: string): string;
function fn(x: number): number;
function fn(x: string | number): string | number {
    if (typeof x === 'string') {
        return x;
    }
    return x;
}

function impossible(x: never): never {
    throw new Error('Impossible');
}

三、void vs never #

3.1 返回类型对比 #

typescript
function returnVoid(): void {
    console.log('Hello');
}

function returnNever(): never {
    throw new Error('Error');
}

3.2 函数行为对比 #

特性 void never
函数是否返回 可能返回 永不返回
返回值 undefined或无
使用场景 无返回值函数 异常/无限循环
类型层级 正常类型 底部类型

3.3 实际对比 #

typescript
function process1(): void {
    console.log('Processing...');
}

function process2(): never {
    throw new Error('Processing failed');
}

function process3(): void {
    if (Math.random() > 0.5) {
        return;
    }
    throw new Error('Random error');
}

四、never的高级应用 #

4.1 穷尽性检查 #

typescript
interface Circle {
    kind: 'circle';
    radius: number;
}

interface Square {
    kind: 'square';
    sideLength: number;
}

interface Triangle {
    kind: 'triangle';
    base: number;
    height: number;
}

type Shape = Circle | Square | Triangle;

function getArea(shape: Shape): number {
    switch (shape.kind) {
        case 'circle':
            return Math.PI * shape.radius ** 2;
        case 'square':
            return shape.sideLength ** 2;
        case 'triangle':
            return (shape.base * shape.height) / 2;
        default:
            const _exhaustiveCheck: never = shape;
            throw new Error(`Unknown shape: ${_exhaustiveCheck}`);
    }
}

4.2 条件类型 #

typescript
type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<string | null>;
type B = NonNullable<null>;
type C = NonNullable<undefined>;

4.3 类型过滤 #

typescript
type Filter<T, U> = T extends U ? never : T;

type Filtered = Filter<'a' | 'b' | 'c', 'a'>;

4.4 排除类型 #

typescript
type Exclude<T, U> = T extends U ? never : T;

type Result = Exclude<'a' | 'b' | 'c', 'a' | 'b'>;

4.5 提取类型 #

typescript
type Extract<T, U> = T extends U ? T : never;

type Result = Extract<'a' | 'b' | 'c', 'a' | 'b'>;

4.6 返回类型never的函数 #

typescript
function assertNever(x: never): never {
    throw new Error('Unexpected object: ' + x);
}

type Shape = 'circle' | 'square';

function area(shape: Shape): number {
    switch (shape) {
        case 'circle':
            return Math.PI;
        case 'square':
            return 1;
        default:
            return assertNever(shape);
    }
}

五、实用示例 #

5.1 类型安全的switch #

typescript
type Status = 'pending' | 'approved' | 'rejected';

function handleStatus(status: Status): string {
    switch (status) {
        case 'pending':
            return 'Waiting for approval';
        case 'approved':
            return 'Approved';
        case 'rejected':
            return 'Rejected';
        default:
            const _exhaustiveCheck: never = status;
            throw new Error(`Unknown status: ${_exhaustiveCheck}`);
    }
}

5.2 API错误处理 #

typescript
class ApiError extends Error {
    constructor(public code: number, message: string) {
        super(message);
    }
}

function assertNever(value: never): never {
    throw new Error(`Unexpected value: ${value}`);
}

function handleErrorCode(code: number): string {
    switch (code) {
        case 400:
            return 'Bad Request';
        case 401:
            return 'Unauthorized';
        case 404:
            return 'Not Found';
        case 500:
            return 'Internal Server Error';
        default:
            return assertNever(code);
    }
}

5.3 Redux Action #

typescript
interface IncrementAction {
    type: 'INCREMENT';
    payload: number;
}

interface DecrementAction {
    type: 'DECREMENT';
    payload: number;
}

interface ResetAction {
    type: 'RESET';
}

type Action = IncrementAction | DecrementAction | ResetAction;

function reducer(state: number, action: Action): number {
    switch (action.type) {
        case 'INCREMENT':
            return state + action.payload;
        case 'DECREMENT':
            return state - action.payload;
        case 'RESET':
            return 0;
        default:
            const _exhaustiveCheck: never = action;
            return state;
    }
}

5.4 类型守卫 #

typescript
function isNever(value: never): void {}

function process(value: string | number | boolean): void {
    if (typeof value === 'string') {
        console.log(value.toUpperCase());
    } else if (typeof value === 'number') {
        console.log(value.toFixed(2));
    } else if (typeof value === 'boolean') {
        console.log(value ? 'true' : 'false');
    } else {
        isNever(value);
    }
}

六、总结 #

本章介绍了TypeScript的void和never类型:

void类型 #

  • 表示没有返回值
  • 用于无返回值的函数
  • 可以返回undefined或null
  • 常用于回调函数和事件处理器

never类型 #

  • 表示永远不会发生的类型
  • 用于永不返回的函数
  • 用于穷尽性检查
  • 用于条件类型过滤

最佳实践 #

  1. 使用void表示无返回值函数
  2. 使用never进行穷尽性检查
  3. 使用never表示不可能的交叉类型
  4. 在条件类型中使用never过滤类型
最后更新:2026-03-26