typescript 中 interface 和 type 有什么区别
·
typescript 中 interface 和 type 有什么区别
1. 定义范围不同
interface仅用于定义对象 / 类的形状(结构类型),无法定义基本类型、联合类型、元组等。type可以定义任意类型,包括基本类型、联合类型、交叉类型、元组、函数类型等,用途更广泛。
示例:
// type 支持基本类型别名
type Str = string;
// type 支持联合类型
type Union = string | number;
// type 支持元组
type Tuple = [string, number];
// interface 只能定义对象结构
interface User {
name: string;
age: number;
}
2. 扩展方式不同
interface通过extends关键字扩展其他接口或类型(仅对象类型)。type通过交叉类型(&),扩展其他类型(支持任意类型的合并)。
示例:
// interface 扩展
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
// type 扩展(交叉类型)
type Animal = { name: string };
type Dog = Animal & { bark(): void };
3. 声明合并(Declaration Merging)
interface支持同名声明自动合并,这是其独有的特性。type不支持同名声明合并,重复定义会直接报错。
示例:
// interface 合并:两个同名接口会合并属性
interface User {
name: string;
}
interface User {
age: number;
}
const user: User = { name: "Tom", age: 18 }; // 合法
// type 重复定义:报错
type User = { name: string };
type User = { age: number }; // 错误:标识符“User”重复
4. 类实现(implements)
interface:可以被类直接implements实现。type:仅当type定义的是纯对象结构时,才能被类implements;若type包含联合类型、交叉类型等复杂类型,则无法被类实现。
示例:
// interface 被类实现
interface Shape {
area(): number;
}
class Circle implements Shape {
area() { return Math.PI * 5 ** 2; }
}
// type 纯对象结构可被实现
type Shape = { area(): number };
class Circle implements Shape {
area() { return Math.PI * 5 ** 2; }
}
// type 联合类型无法被实现
type Shape = { area(): number } | { perimeter(): number };
class Circle implements Shape { // 错误:联合类型不能作为类实现的接口
area() { return Math.PI * 5 ** 2; }
}
5. 映射类型支持
type:天然支持映射类型(如Readonly<T>、Partial<T>),可以基于已有类型生成新类型。interface:不支持映射类型语法,无法直接生成映射类型。
示例:
// type 映射类型(仅type支持)
type ReadonlyUser<T> = {
readonly [P in keyof T]: T[P];
};
type User = { name: string; age: number };
type ReadonlyUser = Readonly<User>; // { readonly name: string; readonly age: number }
6. 函数类型定义
两者都可以定义函数类型,但语法不同:
interface:通过调用签名定义。type:直接定义函数类型。
示例:
// interface 定义函数类型
interface Func {
(a: number): string;
}
const fn: Func = (a) => a.toString();
// type 定义函数类型
type Func = (a: number) => string;
const fn: Func = (a) => a.toString();
如何选择?
- 优先用interface:
- 定义对象 / 类的结构,需要扩展或声明合并时;
- 希望 API 更符合面向对象风格时。
- 优先用type:
- 定义基本类型别名、联合类型、元组、映射类型时;
- 需要组合多种类型(交叉类型)时;
- 定义复杂类型逻辑时。
更多推荐
所有评论(0)