TypeScript:Interface 与 Type 的区别
Interface 和 Type 的用法对比与选择建议
问题
说说你对 TypeScript 的理解,Interface 和 Type 的区别。
解答
TypeScript 是 JavaScript 的超集,添加了静态类型检查。interface 和 type 都可以定义类型,但有一些关键区别。
基本用法
// interface 定义对象类型
interface User {
name: string;
age: number;
}
// type 定义类型别名
type UserType = {
name: string;
age: number;
};
// 两者使用方式相同
const user1: User = { name: 'Alice', age: 25 };
const user2: UserType = { name: 'Bob', age: 30 };
区别一:声明合并
// interface 支持声明合并
interface Animal {
name: string;
}
interface Animal {
age: number;
}
// 自动合并为 { name: string; age: number }
const dog: Animal = { name: 'Max', age: 3 };
// type 不支持声明合并,重复定义会报错
type Plant = { name: string };
// type Plant = { age: number }; // Error: 重复标识符
区别二:扩展方式
// interface 使用 extends 扩展
interface Person {
name: string;
}
interface Employee extends Person {
salary: number;
}
// type 使用交叉类型 & 扩展
type PersonType = {
name: string;
};
type EmployeeType = PersonType & {
salary: number;
};
// 两者可以互相扩展
interface A {
a: string;
}
type B = A & { b: number };
type C = { c: string };
interface D extends C {
d: number;
}
区别三:type 独有的能力
// 1. 定义联合类型
type Status = 'pending' | 'success' | 'error';
type StringOrNumber = string | number;
// 2. 定义元组
type Point = [number, number];
const p: Point = [10, 20];
// 3. 定义基本类型别名
type ID = string;
type Callback = () => void;
// 4. 使用 typeof 获取类型
const config = { api: '/api', timeout: 3000 };
type Config = typeof config; // { api: string; timeout: number }
// 5. 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// 6. 映射类型
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
区别四:interface 独有的能力
// interface 可以被类实现
interface Printable {
print(): void;
}
class Document implements Printable {
print() {
console.log('Printing...');
}
}
// type 也可以被实现,但只限于对象类型
type Loggable = {
log(): void;
};
class Logger implements Loggable {
log() {
console.log('Logging...');
}
}
如何选择
// 推荐使用 interface 的场景:
// 1. 定义对象结构
interface ApiResponse {
code: number;
data: unknown;
message: string;
}
// 2. 需要声明合并(如扩展第三方库类型)
declare global {
interface Window {
myApp: { version: string };
}
}
// 推荐使用 type 的场景:
// 1. 联合类型
type Theme = 'light' | 'dark';
// 2. 元组
type Coordinate = [number, number, number];
// 3. 复杂类型运算
type Partial<T> = { [K in keyof T]?: T[K] };
关键点
- 声明合并:interface 支持,type 不支持
- 扩展语法:interface 用
extends,type 用& - type 更灵活:可定义联合类型、元组、基本类型别名、条件类型
- interface 更语义化:专门用于描述对象结构,支持类实现
- 选择建议:定义对象结构用 interface,需要类型运算用 type
目录