在 TypeScript 中,type 和 interface 的区别

在 TypeScript 中,type 和 interface 的区别

_

TypeScript中的interfacetype都用于定义类型,但它们有一些重要区别:

🎯 基本定义

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

type

对象结构

函数类型

继承/扩展

extends

& 交叉类型

声明合并

✅ 自动合并

❌ 不支持

联合类型

❌ 不支持

✅ 支持

元组类型

❌ 不支持

✅ 支持

条件类型

❌ 不支持

✅ 支持

映射类型

❌ 不支持

✅ 支持

基本类型别名

❌ 不支持

✅ 支持

性能

更快

稍慢

💡 使用场景选择

推荐使用 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 主要用于声明合并和传统对象定义

token 应该存在 Cookie、SessionStorage 还是 LocalStorage 中? 2025-10-23
闭包 2025-09-19

评论区