TypeScript中的interface和type都用于定义类型,但它们有一些重要区别:
🎯 基本定义
interface (接口)
// 定义对象结构
interface User {
id: number;
name: string;
age?: number; // 可选属性
readonly email: string; // 只读属性
}
// 定义函数类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
// 继承
interface AdminUser extends User {
role: 'admin';
}type (类型别名)
// 基本类型别名
type ID = number;
type Name = string;
// 联合类型
type Status = 'pending' | 'completed' | 'failed';
// 对象类型
type User = {
id: number;
name: string;
age?: number;
readonly email: string;
};
// 函数类型
type SearchFunc = (source: string, subString: string) => boolean;
// 条件类型
type ApiResponse<T> = {
data: T;
status: 'success' | 'error';
};🔄 主要区别
1. 继承方式不同
// interface 继承
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// type 继承 (使用交叉类型)
type Animal = {
name: string;
};
type Dog = Animal & {
breed: string;
};
// type 也可以继承 interface
interface Cat {
meow(): void;
}
type Tiger = Cat & {
stripeCount: number;
};2. 合并行为不同
// interface 会自动合并声明
interface User {
id: number;
}
interface User {
name: string; // 两个User会合并
}
// 使用合并后的User
const user: User = {
id: 1,
name: '张三' // ✅ 正确
};
// type 不会合并,会报错
type User = {
id: number;
};
type User = {
name: string; // ❌ 错误:重复标识符
};3. 表达能力不同
// type 可以定义interface不能定义的类型
// 1. 联合类型
type Status = 'pending' | 'completed' | 'failed';
// 2. 元组类型
type Point = [number, number];
// 3. 条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
// 4. 映射类型
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 5. 工具类型组合
type UserProfile = Partial<User> & {
lastLogin: Date;
};
// 6. 基本类型别名
type StringOrNumber = string | number;
// 7. 函数重载
type MyFunction = {
(x: string): string;
(x: number): number;
};🚀 功能对比表
💡 使用场景选择
推荐使用 interface 的场景
// 1. 定义对象结构,特别是API数据模型
interface ApiResponse {
success: boolean;
data: any;
message?: string;
}
// 2. 类的实现
interface Serializable {
serialize(): string;
deserialize(data: string): void;
}
class User implements Serializable {
serialize(): string {
return JSON.stringify(this);
}
deserialize(data: string): void {
// 反序列化逻辑
}
}
// 3. 第三方库的类型定义(支持扩展)
interface Window {
myGlobalFunction(): void;
}
// 其他开发者可以扩展
interface Window {
anotherGlobal(): void;
}推荐使用 type 的场景
// 1. 联合类型
type EventType = 'click' | 'hover' | 'focus';
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
// 2. 工具类型和条件类型
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
// 3. 函数类型别名
type EventHandler<T> = (event: T) => void;
type Validator<T> = (value: T) => boolean;
// 4. 复杂的类型组合
type UserWithPermissions = User & {
permissions: Permission[];
lastLogin: Date | null;
};
// 5. 元组类型
type RGB = [number, number, number];
type Point3D = [number, number, number];
// 6. 模板字面量类型
type ButtonSize = 'small' | 'medium' | 'large';
type ButtonVariant = 'primary' | 'secondary';
type ButtonClass = `btn-${ButtonSize}-${ButtonVariant}`;🔧 混合使用示例
// interface 定义基础结构
interface BaseUser {
id: number;
name: string;
email: string;
}
// type 扩展和组合
type AdminUser = BaseUser & {
role: 'admin';
permissions: Permission[];
};
type GuestUser = Pick<BaseUser, 'id'> & {
isGuest: true;
sessionId: string;
};
// 联合类型
type User = AdminUser | GuestUser;
// 工具函数
type UserGuard = {
isAdmin: (user: User) => user is AdminUser;
isGuest: (user: User) => user is GuestUser;
};
const userGuard: UserGuard = {
isAdmin(user): user is AdminUser {
return user.role === 'admin';
},
isGuest(user): user is GuestUser {
return user.isGuest;
}
};🎯 最佳实践建议
1. 选择原则
// ✅ interface:用于定义对象"形状"
interface User {
id: number;
name: string;
}
// ✅ type:用于类型别名和复杂类型操作
type UserId = number;
type UserName = string;
type UserStatus = 'active' | 'inactive';
type OptionalUser = Partial<User>;
type UserWithStatus = User & { status: UserStatus };2. 团队规范建议
// 团队约定:
// - API数据模型用 interface
// - 工具类型用 type
// - 简单类型别名用 type
// 数据模型
interface UserModel {
id: number;
name: string;
}
// 状态管理
type LoadingState = 'idle' | 'loading' | 'success' | 'error';
// 工具类型
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};3. 性能考虑
// 大型项目中,interface 在编译时性能更好
interface LargeConfig {
// 100+ 个属性
}
// type 复杂类型操作会消耗更多编译资源
type ComplexType<T> = {
[K in keyof T]: T[K] extends string ? `processed_${T[K]}` : T[K];
};📋 总结
选择 interface 当:
✅ 定义对象的"形状"
✅ 需要声明合并
✅ 类的实现
✅ API数据模型
选择 type 当:
✅ 需要联合类型
✅ 需要元组类型
✅ 需要条件类型
✅ 复杂的类型操作
✅ 基本类型别名
现代建议:
优先使用 type,因为它更灵活、功能更强大
interface 主要用于声明合并和传统对象定义