接口与类型别名

Interface 和 Type 是 TypeScript 中定义类型的两种主要方式,理解它们的区别和使用场景至关重要。


接口(Interface)

接口用于定义对象的形状(Shape)。

基本语法

interface User {
  name: string;
  age: number;
  email: string;
}
 
const user: User = {
  name: "Alice",
  age: 25,
  email: "alice@example.com"
};

可选属性

interface Config {
  url: string;
  timeout?: number;  // 可选
  retry?: boolean;   // 可选
}
 
const config: Config = {
  url: "https://api.example.com"
  // timeout 和 retry 可以省略
};

只读属性

interface Point {
  readonly x: number;
  readonly y: number;
}
 
const point: Point = { x: 10, y: 20 };
// point.x = 30; // 错误:只读属性不能修改

索引签名

// 字符串索引
interface StringMap {
  [key: string]: string;
}
 
const colors: StringMap = {
  red: "#ff0000",
  green: "#00ff00"
};
 
// 数字索引
interface NumberArray {
  [index: number]: string;
}
 
const arr: NumberArray = ["a", "b", "c"];

函数类型接口

interface SearchFunc {
  (source: string, keyword: string): boolean;
}
 
const search: SearchFunc = (source, keyword) => {
  return source.includes(keyword);
};

接口继承

interface Animal {
  name: string;
}
 
interface Dog extends Animal {
  breed: string;
}
 
// 多继承
interface Pet extends Animal, Dog {
  owner: string;
}
 
const myDog: Dog = {
  name: "Buddy",
  breed: "Golden Retriever"
};

接口合并(声明合并)

同名接口会自动合并:

interface User {
  name: string;
}
 
interface User {
  age: number;
}
 
// 合并后的 User
const user: User = {
  name: "Alice",
  age: 25
};

类型别名(Type Alias)

Type 可以定义任何类型,不仅仅是对象。

基本语法

type ID = string | number;
type Name = string;
 
// 对象类型
type User = {
  name: string;
  age: number;
};
 
const user: User = {
  name: "Alice",
  age: 25
};

联合类型

type Status = "pending" | "active" | "completed";
type ID = string | number;
 
let status: Status = "active";
let id: ID = 123;
id = "abc";

交叉类型

type Name = {
  name: string;
};
 
type Age = {
  age: number;
};
 
type Person = Name & Age;
 
const person: Person = {
  name: "Alice",
  age: 25
};

元组类型

type Point = [number, number];
type RGB = [number, number, number];
 
const point: Point = [10, 20];
const color: RGB = [255, 128, 0];

函数类型

type Callback = (data: string) => void;
type AsyncCallback = (data: string) => Promise<void>;
 
const log: Callback = (data) => {
  console.log(data);
};

条件类型

type IsString<T> = T extends string ? true : false;
 
type A = IsString<string>;  // true
type B = IsString<number>;  // false

映射类型

type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};
 
type Optional<T> = {
  [K in keyof T]?: T[K];
};

Interface vs Type 对比

特性InterfaceType
对象类型
联合类型
交叉类型❌(用 extends)
元组类型
原始类型别名
声明合并
继承/扩展extends&
实现(implements)

何时使用 Interface

// 1. 定义对象形状
interface User {
  name: string;
  age: number;
}
 
// 2. 需要声明合并(如扩展第三方库类型)
declare global {
  interface Window {
    myCustomProperty: string;
  }
}
 
// 3. 类实现
interface Printable {
  print(): void;
}
 
class Document implements Printable {
  print() {
    console.log("Printing...");
  }
}

何时使用 Type

// 1. 联合类型
type Status = "pending" | "active" | "completed";
 
// 2. 元组
type Coordinates = [number, number];
 
// 3. 复杂类型组合
type Result<T> = { success: true; data: T } | { success: false; error: string };
 
// 4. 工具类型
type Nullable<T> = T | null;
type Keys<T> = keyof T;

高级用法

递归类型

// 树形结构
type TreeNode = {
  value: string;
  children?: TreeNode[];
};
 
// JSON 类型
type JSONValue =
  | string
  | number
  | boolean
  | null
  | JSONValue[]
  | { [key: string]: JSONValue };

模板字面量类型

type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// "onClick" | "onFocus" | "onBlur"
 
type HTTPMethod = "GET" | "POST";
type APIPath = "/users" | "/posts";
type Endpoint = `${HTTPMethod} ${APIPath}`;
// "GET /users" | "GET /posts" | "POST /users" | "POST /posts"

接口与类型的互操作

interface User {
  name: string;
}
 
// Type 可以使用 Interface
type UserWithAge = User & { age: number };
 
// Interface 可以 extends Type
type HasEmail = { email: string };
interface Contact extends HasEmail {
  phone: string;
}

最佳实践

  1. 公共 API 使用 Interface:便于扩展和声明合并
  2. 内部类型使用 Type:更灵活,支持联合类型
  3. 保持一致性:团队内统一风格
  4. 优先组合而非继承:使用交叉类型组合功能
  5. 命名规范:接口不加 I 前缀,类型不加 T 前缀
// 推荐
interface User {}
type UserID = string;
 
// 不推荐
interface IUser {}
type TUserID = string;

typescript 接口 类型别名