Skip to content

TypeScript 接口 Interface

接口是 TypeScript 中非常重要的概念,它定义了对象的结构和类型,是 TypeScript 类型系统的核心组成部分。本章节将详细介绍 TypeScript 接口的使用。

什么是接口?

接口(Interface)是 TypeScript 中用于定义对象结构的一种方式,它描述了对象应该具有哪些属性和方法,以及这些属性和方法的类型。

接口只定义结构,不提供实现,它是一种契约,规定了对象必须满足的条件。

定义对象接口

使用 interface 关键字定义接口:

示例:

typescript
// 定义一个用户接口
interface User {
  id: number;
  name: string;
  email: string;
}

// 使用接口
const user: User = {
  id: 1,
  name: "John",
  email: "john@example.com"
};

// 错误:缺少必要属性
// const invalidUser: User = {
//   id: 2,
//   name: "Jane"
//   // 缺少 email 属性
// };

// 错误:多余属性
// const extraUser: User = {
//   id: 3,
//   name: "Bob",
//   email: "bob@example.com",
//   age: 30 // 多余的 age 属性
// };

可选属性

使用 ? 符号标记可选属性:

示例:

typescript
interface User {
  id: number;
  name: string;
  email: string;
  age?: number; // 可选属性
  address?: string; // 可选属性
}

// 可以不提供可选属性
const user1: User = {
  id: 1,
  name: "John",
  email: "john@example.com"
};

// 也可以提供可选属性
const user2: User = {
  id: 2,
  name: "Jane",
  email: "jane@example.com",
  age: 25,
  address: "123 Main St"
};

只读属性

使用 readonly 关键字标记只读属性:

示例:

typescript
interface User {
  readonly id: number; // 只读属性
  name: string;
  email: string;
}

const user: User = {
  id: 1,
  name: "John",
  email: "john@example.com"
};

// 可以读取只读属性
console.log(user.id); // 1

// 错误:不能修改只读属性
// user.id = 2; // Cannot assign to 'id' because it is a read-only property

任意属性(索引签名)

使用索引签名定义任意属性:

示例:

typescript
// 字符串索引签名
interface User {
  id: number;
  name: string;
  [key: string]: any; // 任意属性,键为字符串,值为任意类型
}

const user: User = {
  id: 1,
  name: "John",
  email: "john@example.com",
  age: 25,
  address: "123 Main St",
  // 可以添加任意其他属性
  phone: "123-456-7890"
};

// 数字索引签名
interface NumberArray {
  [index: number]: number; // 任意属性,键为数字,值为数字
}

const numbers: NumberArray = [1, 2, 3, 4, 5];
console.log(numbers[0]); // 1
console.log(numbers[1]); // 2

接口继承

接口可以继承其他接口,使用 extends 关键字:

示例:

typescript
// 基础接口
interface Person {
  id: number;
  name: string;
  email: string;
}

// 继承 Person 接口
interface Employee extends Person {
  employeeId: number;
  department: string;
  position: string;
}

// 使用 Employee 接口
const employee: Employee = {
  id: 1,
  name: "John",
  email: "john@example.com",
  employeeId: 12345,
  department: "IT",
  position: "Software Engineer"
};

// 继承多个接口
interface Manager extends Employee {
  teamSize: number;
  responsibilities: string[];
}

const manager: Manager = {
  id: 2,
  name: "Jane",
  email: "jane@example.com",
  employeeId: 67890,
  department: "IT",
  position: "Manager",
  teamSize: 10,
  responsibilities: ["Manage team", "Oversee projects"]
};

接口与类型别名 type 的区别

接口和类型别名都可以用来定义对象结构,但它们有一些区别:

特性接口(interface)类型别名(type)
声明合并支持不支持
继承支持(extends)支持(交叉类型 &)
实现可以被类实现(implements)不能被类实现
扩展只能扩展对象类型可以扩展任何类型
语法更简洁,适合对象结构更灵活,适合复杂类型

声明合并

接口支持声明合并,而类型别名不支持:

typescript
// 接口声明合并
interface User {
  id: number;
  name: string;
}

interface User {
  email: string;
  age?: number;
}

// 合并后的 User 接口包含所有属性
const user: User = {
  id: 1,
  name: "John",
  email: "john@example.com",
  age: 25
};

// 类型别名不支持声明合并
// type User = {
//   id: number;
//   name: string;
// };
// 
// type User = {
//   email: string;
// }; // 错误:Duplicate identifier 'User'

类实现

接口可以被类实现,而类型别名不能:

typescript
// 接口可以被类实现
interface Animal {
  name: string;
  makeSound(): void;
}

class Dog implements Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  makeSound(): void {
    console.log("Woof!");
  }
}

// 类型别名不能被类实现
// type AnimalType = {
//   name: string;
//   makeSound(): void;
// };
// 
// class Cat implements AnimalType { // 错误:Cannot implement an interface declared as a type alias
//   name: string;
//   constructor(name: string) {
//     this.name = name;
//   }
//   makeSound(): void {
//     console.log("Meow!");
//   }
// }

实战:定义接口规范数据结构

示例 1:定义 API 响应接口

typescript
// 定义用户接口
interface User {
  id: number;
  name: string;
  email: string;
  age?: number;
  address?: {
    street: string;
    city: string;
    country: string;
  };
}

// 定义 API 响应接口
interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
  error?: {
    code: number;
    message: string;
  };
}

// 使用接口
function fetchUser(): ApiResponse<User> {
  return {
    success: true,
    data: {
      id: 1,
      name: "John",
      email: "john@example.com",
      address: {
        street: "123 Main St",
        city: "New York",
        country: "USA"
      }
    }
  };
}

function fetchError(): ApiResponse<User> {
  return {
    success: false,
    message: "Failed to fetch user",
    error: {
      code: 404,
      message: "User not found"
    }
  };
}

const userResponse = fetchUser();
if (userResponse.success && userResponse.data) {
  console.log(userResponse.data.name); // John
}

const errorResponse = fetchError();
if (!errorResponse.success && errorResponse.error) {
  console.log(errorResponse.error.message); // User not found
}

示例 2:定义表单数据接口

typescript
// 定义表单数据接口
interface LoginForm {
  email: string;
  password: string;
  rememberMe?: boolean;
}

interface RegisterForm {
  name: string;
  email: string;
  password: string;
  confirmPassword: string;
  agreeToTerms: boolean;
}

// 验证登录表单
function validateLoginForm(form: LoginForm): boolean {
  return form.email.length > 0 && form.password.length > 0;
}

// 验证注册表单
function validateRegisterForm(form: RegisterForm): boolean {
  return (
    form.name.length > 0 &&
    form.email.length > 0 &&
    form.password.length >= 8 &&
    form.password === form.confirmPassword &&
    form.agreeToTerms
  );
}

// 使用
const loginForm: LoginForm = {
  email: "john@example.com",
  password: "password123",
  rememberMe: true
};

const registerForm: RegisterForm = {
  name: "John Doe",
  email: "john@example.com",
  password: "password123",
  confirmPassword: "password123",
  agreeToTerms: true
};

console.log(validateLoginForm(loginForm)); // true
console.log(validateRegisterForm(registerForm)); // true

小结

本章节介绍了 TypeScript 接口的使用,包括:

  • 什么是接口
  • 定义对象接口
  • 可选属性
  • 只读属性
  • 任意属性(索引签名)
  • 接口继承
  • 接口与类型别名的区别
  • 实战:定义接口规范数据结构

接口是 TypeScript 类型系统的核心组成部分,它可以帮助你定义清晰、一致的数据结构,提高代码的可维护性和类型安全性。在实际开发中,应该充分利用接口来规范数据结构,特别是在处理 API 响应、表单数据等场景时。

© 2026 编程马·菜鸟教程 版权所有