TypeScript: TypeScript 类型别名 (type)
最后更新:2026-08-26
类型别名(type alias)给类型起一个名字——它不创建新类型,只是给现有类型一个更简短、更有语义的名称。
1. 类型别名的基本语法
(1) 给类型起名
TYPESCRIPT
type ID = number;
type Name = string;
type Active = boolean;
let userId: ID = 42;
let userName: Name = "Charlie";
let isActive: Active = true;
(2) 对象类型别名
TYPESCRIPT
type User = {
name: string;
age: number;
email: string;
};
let user: User = {
name: "Charlie",
age: 20,
email: "xiaoming@example.com"
};
💡 type 和 interface 都能定义对象形状—— 语法略有不同(type 用
=,interface 不用),效果几乎相同。
(3) 函数类型别名
TYPESCRIPT
type GreetFunction = (name: string) => string;
let greet: GreetFunction = (name) => `你好,${name}!`;
console.log(greet("Charlie")); // "你好,Charlie!"
2. 联合类型别名
type 最常见的用途——给联合类型起名,让代码可读性大幅提升:
(1) 字符串联合
TYPESCRIPT
type Status = "pending" | "active" | "completed" | "cancelled";
type Role = "admin" | "editor" | "viewer";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
let orderStatus: Status = "pending";
let userRole: Role = "admin";
let method: HttpMethod = "GET";
(2) 数字联合
TYPESCRIPT
type HttpStatus = 200 | 301 | 400 | 404 | 500;
type Bit = 0 | 1;
let code: HttpStatus = 200;
let flag: Bit = 1;
(3) 混合联合
TYPESCRIPT
type Result = string | Error;
type Id = number | string | undefined;
let output: Result = "成功";
output = new Error("失败"); // ✅ 也合法
▶ 示例:用类型别名描述API响应
TYPESCRIPT
type ApiResponse<T> = {
status: number;
message: string;
data: T;
};
type User = {
id: number;
name: string;
email: string;
};
type UserResponse = ApiResponse<User>;
let response: UserResponse = {
status: 200,
message: "获取成功",
data: { id: 1, name: "Charlie", email: "xiao@example.com" }
};
console.log(`状态:${response.status}`);
console.log(`用户:${response.data.name}`);
输出:
TEXT
📖 仅展示
状态:200
用户:Charlie
3. 交叉类型别名
交叉类型用 & 把多个类型合并为一个——新类型拥有所有类型的全部属性:
(1) 基本语法
TYPESCRIPT
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
let person: Person = {
name: "Charlie",
age: 20
// 必须同时有 name 和 age
};
(2) 实际用途——组合能力
TYPESCRIPT
type HasId = { id: number };
type Timestamped = { createdAt: Date; updatedAt: Date };
type SoftDeletable = { deletedAt: Date | null };
type Entity = HasId & Timestamped & SoftDeletable;
let article: Entity = {
id: 1,
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: null
};
(3) 交叉冲突
当两个类型有同名属性但类型不同时,交叉结果为 never:
TYPESCRIPT
type A = { value: string };
type B = { value: number };
type C = A & B;
// C 的 value 类型是 string & number = never
// 没有任何值能同时是 string 和 number
let c: C = { value: "" }; // ❌ 不能将 string 赋给 never
4. 元组类型别名
TYPESCRIPT
type Point = [x: number, y: number];
type KeyValuePair = [key: string, value: number];
type RGB = [red: number, green: number, blue: number];
let coord: Point = [10, 20];
let entry: KeyValuePair = ["score", 95];
let color: RGB = [255, 128, 0];
// 解构
let [x, y] = coord;
let [key, val] = entry;
5. 模板字面量类型
TypeScript 4.1 引入了模板字面量类型——在类型层面拼接字符串:
(1) 基本语法
TYPESCRIPT
type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// 结果:"onClick" | "onFocus" | "onBlur"
type CSSProperty = "margin" | "padding";
type CSSDirection = "top" | "right" | "bottom" | "left";
type CSSRule = `${CSSProperty}-${CSSDirection}`;
// 结果:"margin-top" | "margin-right" | ... | "padding-left"
(2) 内置字符串操作类型
| 类型 | 作用 | 示例 |
|---|---|---|
Uppercase<S> |
全大写 | Uppercase<"hello"> → "HELLO" |
Lowercase<S> |
全小写 | Lowercase<"HELLO"> → "hello" |
Capitalize<S> |
首字母大写 | Capitalize<"hello"> → "Hello" |
Uncapitalize<S> |
首字母小写 | Uncapitalize<"Hello"> → "hello" |
▶ 示例:类型安全的事件系统
TYPESCRIPT
type EventType = "click" | "change" | "submit";
type HandlerName = `on${Capitalize<EventType>}`;
// "onClick" | "onChange" | "onSubmit"
interface EventHandlers {
onClick?: (x: number, y: number) => void;
onChange?: (value: string) => void;
onSubmit?: (data: FormData) => void;
}
// 使用——handler 名字有类型提示,不会拼错
let handlers: EventHandlers = {
onClick: (x, y) => console.log(`点击:(${x}, ${y})`),
onChange: (value) => console.log(`值改变:${value}`)
};
6. type vs interface 完整对比
(1) 能力对比
| 能力 | type | interface |
|---|---|---|
| 对象类型 | ✅ type T = { ... } |
✅ interface T { ... } |
| 联合类型 | ✅ type T = A | B |
❌ |
| 交叉类型 | ✅ type T = A & B |
用 extends 代替 |
| 基本类型别名 | ✅ type T = string |
❌ |
| 元组类型 | ✅ type T = [A, B] |
❌ |
| 模板字面量 | ✅ type T = \...`` |
❌ |
| 声明合并 | ❌ | ✅ |
| class implements | ✅ | ✅ |
| extends 继承 | 用 & | ✅ extends |
| 计算属性键 | ✅ [K in Keys] |
❌ |
(2) 选择策略
TEXT
📖 仅展示
需要的功能 → 选择
───────────────────────────────
联合类型 A | B → type
基本类型别名 → type
元组 [A, B] → type
模板字面量类型 → type
对象形状 + 需要继承 → interface
对象形状 + 声明合并 → interface
简单的对象形状 → 都可以,团队统一即可
❓ 常见问题
Q type 能用 extends 继承吗?
A type 没有 extends 语法,但可以用交叉类型
& 实现类似效果——type Child = Parent & { extra: string }。interface 的 extends 更清晰且能检测冲突,交叉类型冲突时产生 never 不会报错(只是类型变不可用)。Q type 能被 class implements 吗?
A 可以。只要 type 定义的是对象类型(不含联合、基本类型等),class 就可以 implements 它。
class User implements UserType { ... } 完全合法。Q 什么时候必须用 type 不能用 interface?
A 三种场景:(1) 联合类型——interface 无法表达 A | B (2) 元组类型——interface 虽然能写但非常别扭 (3) 模板字面量类型——interface 不支持。其余场景两者等价,选哪个都行。
Q 模板字面量类型有什么实际用途?
A 主要用于高级类型编程——自动生成事件名(onClick/onFocus)、CSS属性组合(margin-top)、路由路径类型推导等。日常开发中不常用,但在框架和库的类型定义中非常强大。初学者了解即可。
📖 小节
- type 别名给现有类型起名字,不创建新类型;语法
type Name = 类型 - 联合类型别名是 type 最常见的用途——让复杂联合类型可读、可复用
- 交叉类型
A & B合并多个类型的全部属性,冲突时产生 never - 模板字面量类型在类型层面拼接字符串,配合内置操作类型(Uppercase 等)
- type 和 interface 大部分场景等价;联合类型、元组、模板字面量必须用 type
📝 作业
- 基础题(难度⭐):用 type 定义
StatusCode = 200 | 404 | 500,然后定义ApiResponse<T> = { code: StatusCode; data: T }。创建一个ApiResponse<string>实例并输出。 - 进阶题(难度⭐⭐):用交叉类型组合
HasId、HasTimestamps、HasAudit三个类型,定义一个完整的Entity类型。创建一个实例对象,确保所有属性都满足。 - 挑战题(难度⭐⭐⭐):用模板字面量类型定义
CSSDirection = "top" | "right" | "bottom" | "left",然后生成MarginStyle = { [K inmargin-${CSSDirection}]: number }。验证生成的类型包含 marginTop、marginRight 等属性。