在 TypeScript 中,接口(Interface) 是一种强大的工具,用于定义对象的形状(即对象的结构和类型)。接口的主要作用是提供一种约定,确保对象符合特定的结构,从而增强代码的可读性、可维护性和类型安全性。
以下是接口的主要作用和使用场景:
1. 定义对象的形状
接口最常见的用途是描述对象的属性和方法。
TypeScript
interface Person {
name: string;
age: number;
greet(): void;
}
const user: Person = {
name: "Alice",
age: 25,
greet() {
console.log(`Hello, my name is ${this.name}`);
},
};
2. 实现代码的可重用性
接口可以定义通用的结构,供多个对象或类实现。
使用接口限制类时,需要使用implements关键字!
TypeScript
interface Animal {
name: string;
speak(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`${this.name} barks.`);
}
}
class Cat implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`${this.name} meows.`);
}
}
3. 增强类型检查
接口可以在编译时检查对象是否符合预期的结构,从而减少运行时错误。
TypeScript
interface User {
id: number;
username: string;
}
function printUser(user: User) {
console.log(`ID: ${user.id}, Username: ${user.username}`);
}
printUser({ id: 1, username: "Alice" }); // 合法
printUser({ id: 2 }); // 报错:缺少 username 属性
4. 可选属性
接口可以定义可选属性,使对象的结构更加灵活。
TypeScript
interface Config {
url: string;
timeout?: number; // 可选属性
}
const config: Config = {
url: "https://example.com",
};
5. 只读属性
接口可以定义只读属性,防止属性被修改。
TypeScript
interface Point {
readonly x: number;
readonly y: number;
}
const p: Point = { x: 10, y: 20 };
p.x = 5; // 报错:无法修改只读属性
6. 函数类型
接口可以描述函数的形状,包括参数和返回值。
TypeScript
interface SearchFunc {
(source: string, keyword: string): boolean;
}
const search: SearchFunc = (source, keyword) => {
return source.includes(keyword);
};
7. 索引签名
接口可以定义索引签名,用于描述动态属性的类型。
TypeScript
interface StringArray {
[index: number]: string;
}
const arr: StringArray = ["Alice", "Bob"];
console.log(arr[0]); // Alice
8. 接口继承
接口可以通过extends关键字继承扩展其他接口。
TypeScript
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
employeeId: number;
}
const employee: Employee = {
name: "Alice",
age: 25,
employeeId: 123,
};
9. 类实现接口
类可以通过 implements
关键字实现接口,确保类符合接口的结构。
TypeScript
interface Vehicle {
start(): void;
stop(): void;
}
class Car implements Vehicle {
start() {
console.log("Car started");
}
stop() {
console.log("Car stopped");
}
}
10. 接口合并
如果定义了多个同名接口,TypeScript 会自动合并它们。
TypeScript
interface Box {
width: number;
}
interface Box {
height: number;
}
const box: Box = {
width: 10,
height: 20,
};
11. 描述复杂类型
接口可以与其他高级类型(如联合类型、交叉类型)结合,描述更复杂的结构。
TypeScript
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
// 使用type定义联合类型
// |:(相当于 或 的意思)
type Pet = Bird | Fish;
function move(pet: Pet) {
if ("fly" in pet) {
pet.fly();
} else {
pet.swim();
}
}
12. 接口与类型别名(Type)的区别
接口和类型别名(type
)功能相似,但有以下区别:
-
接口:
-
更适合定义对象的形状。
-
支持继承(
extends
)和合并。
-
-
类型别名:
-
更适合定义联合类型、交叉类型或复杂类型。
-
不支持合并。
-
总结
接口在 TypeScript 中的主要作用包括:
-
定义对象的形状。
-
增强类型检查,减少运行时错误。
-
提高代码的可读性和可维护性。
-
支持可选属性、只读属性、函数类型等高级特性。
-
通过继承和合并扩展接口的功能。
接口是 TypeScript 类型系统的核心特性之一,广泛应用于定义数据结构、函数签名和类的契约。