介绍
type 用于给任意类型起别名,简化重复复杂类型书写,复用类型。
作用
仅用于 TypeScript 静态类型检查,编译转换为 JavaScript 后会被全部移除,不会生成任何运行时代码。
应用场景
- 接口请求状态:loading /success/fail
- 订单状态:待付款、已发货、已完成、已取消
- 权限角色:admin /user/guest
- 性别、文件类型、支付方式
- 后端主键有时候数字、有时候字符串(雪花 ID / 数字自增)
基础语法
type 别名名称 = 类型表达式;
区别于 interface:
interface只能描述对象/类结构,支持自动合并、extends继承;type支持所有类型:基础类型、联合、交叉、元组、函数、递归类型、泛型,不能同名合并。
基础用法
1. 基础原始类型别名
给简单基础类型起短名,统一项目规范
// 原始类型
type TString = string;
type TNumber = number;
type TBoolean = boolean;
type TNull = null;
type TUndefined = undefined;
// 使用
const name: TString = "张三";
const age: TNumber = 20;
2. 字面量类型(字符串/数字/布尔字面量)
限定变量只能取固定值,常用于状态、枚举替代
// 字符串字面量联合
type Status = "success" | "fail" | "loading";
let resStatus: Status = "loading";
// resStatus = "xxx" // 报错,只能指定三个值
// 数字字面量
type Level = 1 | 2 | 3;
const lv: Level = 2;
// 布尔字面量
type TrueOnly = true;
const flag: TrueOnly = true;
3. 对象类型(最常用)
支持可选属性、只读属性、任意索引签名
type User = {
// 必填属性
id: number;
name: string;
// 可选属性 ?
avatar?: string;
// 只读属性 readonly,无法修改
readonly createTime: number;
// 索引签名:支持任意字符串key,值为string
[key: string]: string | number | undefined;
};
const user: User = {
id: 1,
name: "李四",
createTime: Date.now(),
phone: "13800000000"
};
// user.createTime = 123; // 报错:只读无法修改
user.avatar = "xxx.png"; // 可选属性可后期赋值
4. 函数类型别名
统一约束函数入参、返回值类型
// 普通函数
type AddFn = (a: number, b: number) => number;
const add: AddFn = (x, y) => x + y;
// 无返回值 void
type LogFn = (msg: string) => void;
const log: LogFn = (msg) => console.log(msg);
// 带可选参数
type SayFn = (name: string, age?: number) => string;
5. 元组类型 Tuple
固定长度、固定每个位置类型的数组
type Point = [number, number]; // 坐标 x,y
const p: Point = [10, 20];
// 复杂元组 + 可选元素
type Info = [string, number, boolean?];
const info1: Info = ["小明", 18];
const info2: Info = ["小红", 20, true];
6. 数组类型简写
type NumArr = number[];
type StrArr = string[];
// 等价泛型写法
type NumArr2 = Array<number>;
高级运算符:联合 |、交叉 &
1. 联合类型 |:满足任意一种类型
多个类型或关系,变量可以是其中任意一种
// 数字/字符串ID
type Id = number | string;
const id1: Id = 1001;
const id2: Id = "1002";
// 对象联合
type Cat = { meow(): void };
type Dog = { bark(): void };
type Pet = Cat | Dog;
// 注意:联合类型不能直接访问独有属性,需要类型守卫
const pet: Pet = { meow: () => {} };
// pet.meow() 直接报错
if ("meow" in pet) pet.meow(); // 类型缩小后可用
2. 交叉类型 &:同时满足所有类型(合并对象)
多个类型且关系,融合所有属性
type A = { id: number };
type B = { name: string };
type UserInfo = A & B;
const u: UserInfo = { id: 1, name: "老王" };
// 冲突属性:相同key不同类型会变成 never
type Conflict = { a: string } & { a: number };
// type Conflict = { a: never } 无法赋值
联合 vs 交叉对比
A | B:二选一A & B:两者全部拥有
泛型 type(通用可复用类型)
给类型添加泛型参数,适配任意数据结构,项目接口返回体必备
基础泛型
// 通用接口返回结构
type ApiResponse<T> = {
code: number;
data: T;
message: string;
};
// 用户类型
type User = { uid: string; username: string };
// 用户响应类型,传入 User 替换 T
type UserResp = ApiResponse<User>;
const resp: UserResp = {
code: 200,
data: { uid: "u001", username: "张三" },
message: "成功"
};
多泛型参数
type Pair<T, K> = { key: T; value: K };
const pair: Pair<string, number> = { key: "count", value: 10 };
泛型约束 extends
限制泛型必须满足指定结构
type HasId = { id: number };
type ItemResp<T extends HasId> = { list: T[] };
type Book = { id: number; title: string };
const bookList: ItemResp<Book> = { list: [{ id: 1, title: "TS教程" }] };
类型提取工具(配合 type 高频使用)
1. typeof:提取变量的类型
从已有变量反向生成类型,不用重复定义
const userObj = { id: 1, name: "小李" };
type UserType = typeof userObj;
// 等价 type UserType = { id: number; name: string }
2. keyof:提取对象所有键的联合类型
type User = { id: number; name: string };
type UserKeys = keyof User; // "id" | "name"
// 工具函数约束对象key
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
3. 内置工具类型(全部基于 type 实现)
Partial:所有属性变为可选
type User = { id: number; name: string };
type PartialUser = Partial<User>;
// { id?: number | undefined; name?: string | undefined }
Required:所有属性变为必填
type RequiredUser = Required<PartialUser>;
Readonly:所有属性只读
type ReadOnlyUser = Readonly<User>;
Pick:挑选指定属性生成新类型
type SimpleUser = Pick<User, "id">; // { id: number }
Omit:剔除指定属性生成新类型
type UserWithoutId = Omit<User, "id">; // { name: string }
Exclude:从联合中剔除类型
type AllStatus = "success" | "fail" | "loading";
type SuccessStatus = Exclude<AllStatus, "fail" | "loading">;
// "success"
Extract:提取联合中匹配的类型
type FailStatus = Extract<AllStatus, "fail">;
ReturnType:提取函数返回值类型
const fn = () => ({ id: 1 });
type FnReturn = ReturnType<typeof fn>; // { id: number }
常量断言 as const 配合 type 锁定字面量
普通数组是 string[],as const 转为固定字面量联合
const roles = ["admin", "visitor"] as const;
type Role = (typeof roles)[number]; // "admin" | "visitor"
递归 type(树形、嵌套结构)
type 支持自引用递归,用于菜单、树形数据
type TreeNode = {
label: string;
children?: TreeNode[]; // 递归引用自身
};
const tree: TreeNode = {
label: "根目录",
children: [
{ label: "子节点1" },
{ label: "子节点2", children: [{ label: "孙子节点" }] }
]
};
type 扩展对象(交叉 &)vs interface extends
type 扩展:交叉 &
type Base = { id: number };
type User = Base & { name: string };
interface 扩展:extends
interface Base { id: number }
interface User extends Base { name: string }
核心区别汇总
| 功能 | type 类型别名 | interface 接口 |
|---|---|---|
| 原始/联合/元组/函数 | ✅ 支持 | ❌ 不支持 |
| 对象描述 | ✅ | ✅ |
| 同名重复定义 | ❌ 直接报错 | ✅ 自动合并 |
| 继承扩展 | 使用 & 交叉 |
使用 extends |
| 配合 class 实现 | 可以,但不推荐 | 推荐 |
| 递归类型 | ✅ 支持 | ✅ 支持 |
使用场景选择
- 优先用
type- 定义联合、交叉、元组、函数、简单类型别名
- 一次性复合类型,不需要外部扩展合并
- 优先用
interface- 定义类、实体对象,需要多处扩展、同名合并
- 面向面向对象开发(class implements)
常见坑与易错点
1. type 不允许重复同名定义
type T = { a: number };
type T = { b: string }; // 报错:重复标识符
interface 同名会自动合并,type 不行。
2. 联合类型无法直接访问独有属性
需要用 in / 类型判断缩小类型范围才能访问独有字段。
3. 交叉类型属性冲突会变成 never
type T = { x: string } & { x: number };
// T["x"] = never,无法赋值任何值
4. type 不能用于类 implements 限制(不推荐)
class 实现接口优先用 interface,type 虽然能运行但不符合规范。
5. 区分类型别名和值变量
type 仅存在于编译期,打包后会被删除,运行时不存在,不能当做变量使用。
案例
后端接口类型封装
// 1. 基础状态、编码字面量
type ResCode = 200 | 401 | 404 | 500;
type OperateStatus = "ok" | "error";
// 2. 通用泛型返回体
type ApiResult<T> = {
code: ResCode;
status: OperateStatus;
data: T;
msg: string;
};
// 3. 业务实体
type User = {
userId: string;
username: string;
readonly createAt: number;
avatar?: string;
};
// 4. 分页包装类型
type PageData<T> = {
list: T[];
total: number;
pageNum: number;
pageSize: number;
};
// 5. 组合业务类型
type UserPageResp = ApiResult<PageData<User>>;
// 模拟接口返回
function getUserPage(): UserPageResp {
return {
code: 200,
status: "ok",
msg: "查询成功",
data: {
list: [{ userId: "u001", username: "张三", createAt: 1780000000 }],
total: 1,
pageNum: 1,
pageSize: 10
}
};
}