类型别名(Type Alias)
概述
类型别名使用 type 关键字为类型创建新名称,可以用于任何类型,包括原始类型、联合类型、元组等。
基本语法
简单类型别名
// 原始类型别名
type ID = string | number;
type Name = string;
type Age = number;
// 使用类型别名
let userId: ID = 123;
userId = 'abc';
let userName: Name = 'John';
let userAge: Age = 25;
对象类型别名
// 对象类型别名
type User = {
id: number;
name: string;
email: string;
};
type Product = {
id: number;
name: string;
price: number;
inStock: boolean;
};
const user: User = {
id: 1,
name: 'John',
email: 'john@example.com'
};
函数类型别名
// 函数类型别名
type Add = (a: number, b: number) => number;
type Callback = (data: string) => void;
type Predicate<T> = (item: T) => boolean;
const add: Add = (a, b) => a + b;
const callback: Callback = (data) => console.log(data);
const isEven: Predicate<number> = (n) => n % 2 === 0;
联合类型别名
// 联合类型
type StringOrNumber = string | number;
type Status = 'active' | 'inactive' | 'pending';
type Result<T> = { success: true; data: T } | { success: false; error: string };
function processValue(value: StringOrNumber): string {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value.toString();
}
function handleResult<T>(result: Result<T>): T | null {
if (result.success) {
return result.data;
}
console.error(result.error);
return null;
}
交叉类型别名
// 交叉类型
type Person = {
name: string;
age: number;
};
type Employee = {
employeeId: number;
department: string;
};
type EmployeePerson = Person & Employee;
const employee: EmployeePerson = {
name: 'John',
age: 25,
employeeId: 123,
department: 'Engineering'
};
泛型类型别名
// 泛型类型别名
type ApiResponse<T> = {
data: T;
status: number;
message: string;
};
type User = { id: number; name: string };
type UserResponse = ApiResponse<User>;
type UsersResponse = ApiResponse<User[]>;
type Container<T> = {
value: T;
getValue: () => T;
setValue: (value: T) => void;
};
// 使用泛型类型别名
const userResponse: UserResponse = {
data: { id: 1, name: 'John' },
status: 200,
message: 'Success'
};
条件类型别名
// 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// 更复杂的条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
type C = NonNullable<string | null>; // string
type D = NonNullable<number | undefined>; // number
映射类型别名
// 映射类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Optional<T> = {
[P in keyof T]?: T[P];
};
type User = {
id: number;
name: string;
email: string;
};
type ReadonlyUser = Readonly<User>;
type OptionalUser = Optional<User>;
实际应用示例
1. 状态管理
type LoadingState = {
status: 'loading';
};
type SuccessState<T> = {
status: 'success';
data: T;
};
type ErrorState = {
status: 'error';
error: string;
};
type AsyncState<T> = LoadingState | SuccessState<T> | ErrorState;
function handleState<T>(state: AsyncState<T>): void {
switch (state.status) {
case 'loading':
console.log('Loading...');
break;
case 'success':
console.log('Data:', state.data);
break;
case 'error':
console.log('Error:', state.error);
break;
}
}
2. 表单类型
type FormField<T> = {
value: T;
error?: string;
touched: boolean;
};
type LoginForm = {
username: FormField<string>;
password: FormField<string>;
remember: FormField<boolean>;
};
type FormValidation<T> = {
[K in keyof T]: T[K] extends FormField<infer U> ? (value: U) => string | undefined : never;
};
3. 事件处理
type EventType = 'click' | 'focus' | 'blur' | 'submit';
type EventHandler<T extends EventType = 'click'> =
T extends 'click' ? (event: MouseEvent) => void :
T extends 'focus' | 'blur' ? (event: FocusEvent) => void :
T extends 'submit' ? (event: SubmitEvent) => void :
never;
type EventHandlers = {
[K in EventType]?: EventHandler<K>;
};
类型别名 vs 接口
相似之处
// 两者都可以定义对象类型
interface UserInterface {
id: number;
name: string;
}
type UserType = {
id: number;
name: string;
};
类型别名的优势
// 1. 联合类型
type StringOrNumber = string | number;
// 2. 元组类型
type Tuple = [string, number, boolean];
// 3. 原始类型别名
type ID = string | number;
// 4. 条件类型
type IsString<T> = T extends string ? true : false;
// 5. 映射类型
type Readonly<T> = { readonly [P in keyof T]: T[P] };
接口的优势
// 1. 扩展
interface User {
id: number;
name: string;
}
interface Employee extends User {
employeeId: number;
}
// 2. 声明合并
interface User {
id: number;
}
interface User {
name: string;
}
// 合并后:User 有 id 和 name 属性
最佳实践
- 使用类型别名定义联合类型和元组
- 使用接口定义对象类型
- 使用泛型类型别名提高复用性
- 避免过度使用类型别名
// 好的做法
type ID = string | number;
type Status = 'active' | 'inactive' | 'pending';
type ApiResponse<T> = { data: T; status: number };
interface User {
id: ID;
name: string;
status: Status;
}
// 避免
type User = {
id: ID;
name: string;
status: Status;
}; // 接口更适合对象类型
参考
目录