🧩 一、基础相同点
无论是 interface 还是 type,都可以用来定义对象的结构:
interface Person {
name: string;
age: number;
}
type Person = {
name: string;
age: number;
};
这两种写法在最常见的场景下是等价的。
但区别出现在更复杂的情况。
🚀 二、主要区别
1️⃣ interface 可以被 继承(extends)
interface 支持多重继承:
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
type 也能实现类似的效果,但要用 交叉类型(&) :
type Animal = { name: string };
type Dog = Animal & { bark(): void };
🟢 结论:都能实现继承,但 interface 语义更清晰,专为扩展设计。
2️⃣ interface 可以被 合并声明(declaration merging)
interface User {
name: string;
}
interface User {
age: number;
}
const u: User = {
name: "Alice",
age: 18,
};
✅ 这里两个 interface User 会自动合并成一个类型 { name: string; age: number; }
但 type 不行:
type User = { name: string };
type User = { age: number }; // ❌ 报错:重复定义
🟢 结论:
interface 支持声明合并,非常适合定义库类型或扩展第三方类型。
type 则不支持重复声明。
3️⃣ type 更灵活:能表示联合类型、交叉类型、原始类型、条件类型等
type Status = "success" | "error" | "pending"; // 联合类型
type Id = number | string; // 可以是多种类型
type Response<T> = T extends string ? string[] : T[]; // 条件类型
这些是 interface 做不到的。
🟢 结论:
type 更像是 “类型别名” ,可以为任何类型起名字;
interface 只用于描述 对象结构。
4️⃣ interface 只能描述 对象形状,type 可以描述 一切
type Fn = (x: number) => void; // ✅ 函数类型
type Pair = [string, number]; // ✅ 元组类型
type Primitive = string | number; // ✅ 原始类型或联合类型
interface Fn { (x: number): void } // ✅ 也能描述函数签名
interface Pair extends Array<any> {} // ⚠️ 但写法较怪
🟢 结论:
type 的使用范围更广,能表示几乎所有 TS 类型。
interface 更专注于结构化对象。
5️⃣ 在工具类型与泛型中的表现
type 与 interface 都支持泛型:
type Box<T> = { value: T };
interface Box<T> { value: T }
但在使用 条件类型 或 映射类型(如 Partial<T>、Pick<T>)时,type 更自然。
🧠 三、怎么选?
| 场景 | 推荐 |
|---|---|
| 定义对象结构 | ✅ interface(语义清晰、支持扩展) |
| 定义联合、交叉、映射、条件类型 | ✅ type |
| 需要被第三方扩展(如声明合并) | ✅ interface |
| 想表达任意类型组合 | ✅ type |
| 定义函数签名或工具类型 | 通常用 type |
🧩 四、实际项目中建议
-
优先使用
interface:当你只是定义对象结构、类的约束; -
使用
type:当你需要更复杂的类型操作(联合、交叉、映射、条件); -
如果不确定,记住这条经验法则👇
“能用 interface 就用 interface;必须用 type 再用 type。”