TypeScript 类型别名
类型别名(Type Alias) 是 TypeScript 中另一个重要的类型定义方式,使用 type 关键字为任意类型创建一个新的名字。
如果说接口是一份“契约”,那么类型别名更像是一个“绰号”——它不创造新的类型,只是给现有类型起一个更直观的名字,方便复用。
和接口一样,类型别名只在编译时存在,编译成 JavaScript 后会被完全删除。
基础用法
类型别名可以描述任何类型,这是它和接口最大的不同。
给基本类型起别名
// 给 string 起别名
type Username = string
type Age = number
let user: Username = '张三'
let userAge: Age = 25
// 注意:虽然起了别名,但本质上还是 string/number,所以赋值时兼容
let rawString: string = '李四'
user = rawString // ✅ 可以,因为 Username 本质上就是 string
给对象类型起别名
type User = {
id: number
name: string
email: string
}
function register(user: User) {
// ...
}
register({ id: 1, name: '王五', email: 'wang@example.com' })
提示:给对象类型起别名时,效果上非常像接口,但语法用 = 赋值。
独特优势
类型别名最常用的场景是定义联合类型(Union Type)——这恰恰是接口做不到的。
// 定义状态值只能是指定的几个字符串之一
type Status = 'pending' | 'success' | 'error'
let currentStatus: Status
currentStatus = 'pending' // ✅
currentStatus = 'success' // ✅
// currentStatus = 'failed' // ❌ 类型 '"failed"' 不能赋值给类型 'Status'
// 定义 ID 可以是数字或字符串
type ID = number | string
function getItem(id: ID) {
console.log(`获取商品:${id}`)
}
getItem(123) // ✅
getItem('ABC') // ✅
交叉类型
使用 & 可以将多个类型合并成一个,类似接口的继承:
type BaseInfo = {
name: string
age: number
}
type ContactInfo = {
phone: string
email: string
}
// 合并两个类型
type Person = BaseInfo & ContactInfo
const p: Person = {
name: '赵六',
age: 30,
phone: '13800138000',
email: 'zhao@example.com',
}
接口 vs 类型别名
这是新手最常问的问题,大部分场景两者可以互换,但各有侧重。
声明合并
接口支持“声明合并”,类型别名不支持。
同名接口会自动合并,这在扩展第三方库类型时非常有用:
// 第一次声明
interface User {
id: number
}
// 第二次声明同名接口,会自动合并
interface User {
name: string
}
// 最终 User 等同于 { id: number; name: string }
const u: User = { id: 1, name: '小明' } // ✅
// type 不支持重复定义
type UserType = { id: number }
// type UserType = { name: string } // ❌ 报错:标识符 "UserType" 重复
描述范围
类型别名可以描述联合、元组、基本类型。
// 这些接口都做不到
type Status = 'on' | 'off' // 联合字面量
type Tuple = [string, number] // 元组
type Primitive = string | number // 基本类型联合
扩展方式
扩展方式不同:extends vs &。
// 接口用 extends
interface Animal { name: string }
interface Dog extends Animal { bark(): void }
// 类型别名用 &
type AnimalType = { name: string }
type DogType = AnimalType & { bark(): void }
决策指南
| 场景 | 推荐 |
|---|---|
| 定义对象的结构,且后续可能扩展 | 接口 interface |
| 定义联合类型、元组、基本类型别名 | 类型别名 type |
| 需要声明合并能力(如扩展第三方库) | 接口 interface |
| 定义函数签名 | 两者均可,但推荐接口(更清晰) |
| 不确定时 | 优先用接口,遇到需要联合类型时再用 type |