TypeScript void与never #
一、void类型 #
1.1 什么是void #
void类型表示没有任何类型,通常用于表示函数没有返回值。
typescript
function log(message: string): void {
console.log(message);
}
log('Hello, TypeScript!');
1.2 void的特点 #
- 表示没有返回值
- 只能赋值
undefined或null(非严格模式) - 常用于函数返回类型
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类型 #
- 表示永远不会发生的类型
- 用于永不返回的函数
- 用于穷尽性检查
- 用于条件类型过滤
最佳实践 #
- 使用void表示无返回值函数
- 使用never进行穷尽性检查
- 使用never表示不可能的交叉类型
- 在条件类型中使用never过滤类型
最后更新:2026-03-26