Typescript 中 Type 和 Interface 的区别
在 TypeScript 中,interface 和 type 都可以用来定义类型,但它们有一些关键的区别。了解这些区别有助于你在不同的场景中选择合适的方式。
1. 基本语法
Interface
interface Person {
name: string
age: number
}
Type
type Person = {
name: string
age: number
}
2. 扩展和合并
Interface
interface 支持声明合并,即多个同名的 interface 会自动合并成一个。
interface Person {
name: string
}
interface Person {
age: number
}
// 等价于
interface Person {
name: string
age: number
}
Type
type 不支持声明合并。如果你尝试定义多个同名的 type,编译器会报错。
type Person = {
name: string
}
// 编译错误:Duplicate identifier 'Person'.
type Person = {
age: number
}
3. 继承和交叉类型
Interface
interface 可以继承其他 interface,支持多重继承。
interface Named {
name: string
}
interface Person extends Named {
age: number
}
const p: Person = { name: 'Alice', age: 30 }
Type
type 可以使用交叉类型 (&) 来模拟继承。
type Named = {
name: string
}
type Person = Named & {
age: number
}
const p: Person = { name: 'Alice', age: 30 }
4. 泛型
Interface
interface 可以定义泛型。
interface Box<T> {
value: T
}
const box: Box<number> = { value: 42 }
Type
type 也可以定义泛型。
type Box<T> = {
value: T
}
const box: Box<number> = { value: 42 }
5. 联合类型和元组
Type
type 更适合定义联合类型和元组。
type Message = string | number
type Coordinates = [number, number]
6. 计算属性和映射类型
Type
type 支持计算属性和映射类型,这在某些高级类型操作中非常有用。
type EventHandlers = {
[K in 'onOpen' | 'onClose']: () => void
}
const handlers: EventHandlers = {
onOpen: () => console.log('Opened'),
onClose: () => console.log('Closed'),
}
7. 枚举和命名空间
Interface
interface 不能直接用于枚举和命名空间。
Type
type 也不能直接用于枚举和命名空间,但可以用于定义枚举和命名空间中的类型。
enum Status {
Open,
Closed,
}
type StatusType = keyof typeof Status
总结
- Interface:
- 支持声明合并。
- 支持继承。
- 适用于定义对象形状和接口。
- Type:
- 不支持声明合并。
- 适用于定义联合类型、元组、计算属性和映射类型。
- 适用于更复杂的类型操作。
通过了解这些区别,你可以根据具体的需求选择合适的类型定义方式。