在 TypeScript 中,接口(Interface) 是一种强大的工具,用于定义对象的形状(Shape),也就是对象的结构和类型。接口的主要作用是 为 JavaScript 对象提供类型约束,从而在开发阶段捕获潜在的错误,提高代码的可读性和可维护性。
接口的作用和适用场景非常广泛,下面我会详细讲解接口的作用以及它主要针对的数据类型。
(具体进行类型检验的节点可参照:TS接口:2.接口进行格式检查的节点)
1. 接口的作用(其实都是围绕提供类型约束的)
1.1 定义对象的形状
接口最常见的用途是定义对象的结构,包括对象的属性、方法以及它们的类型。
interface User {
name: string;
age: number;
isActive?: boolean; // 可选属性
}
const user: User = {
name: "Alice",
age: 25,
};
- 这里
User
接口定义了对象的形状,确保user
对象必须包含name
和age
属性。
1.2 提供类型检查
接口可以在编译时对代码进行静态类型检查,确保对象符合预期的结构。
function printUser(user: User) {
console.log(user.name, user.age);
}
printUser({ name: "Bob", age: 30 }); // 正常
printUser({ name: "Bob" }); // 报错:缺少 age 属性
1.3 支持代码复用
通过接口,可以定义通用的类型约束,并在多个地方复用。
interface Point {
x: number;
y: number;
}
function printPoint(point: Point) {
console.log(`x: ${point.x}, y: ${point.y}`);
}
const p1: Point = { x: 10, y: 20 };
const p2: Point = { x: 30, y: 40 };
1.4 支持继承(接口的一个特点,继承特性也是服务于如何拓展类型约束这一问题的)
接口可以通过 extends
关键字继承其他接口,实现类型的扩展和复用。
interface Person {
name: string;
}
interface Employee extends Person {
employeeId: number;
}
const emp: Employee = {
name: "Alice",
employeeId: 123,
};
1.5 支持类实现(拓展了类型约束这一功能的适用范围到类)
类可以通过 implements
关键字实现接口,确保类符合接口的定义。
interface Animal {
name: string;
makeSound(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound() {
console.log("Woof!");
}
}
1.6 支持函数类型(拓展了类型约束这一功能的适用范围到函数)
接口可以描述函数的类型,包括参数和返回值。
interface SearchFunc {
(source: string, subString: string): boolean;
}
const mySearch: SearchFunc = function (src, sub) {
return src.includes(sub);
};
1.7 支持可索引类型(也是围绕类型约束来的,大致理解是使得约束成了一个范围而不是具体的几个什么属性)
(针对索引类型具体应用可参照:TS接口:3.可索引类型)
接口可以描述可以通过索引访问的类型,比如数组或对象。
interface StringArray {
[index: number]: string;
}
const arr: StringArray = ["a", "b", "c"];
2. 接口针对的数据类型
接口主要用于描述 对象类型,但它也可以用于描述其他数据类型:
2.1 对象类型
接口最常见的用途是描述对象的形状。
interface Person {
name: string;
age: number;
}
2.2 函数类型
接口可以描述函数的类型。
interface AddFunc {
(a: number, b: number): number;
}
const add: AddFunc = function (a, b) {
return a + b;
};
2.3 数组类型
接口可以描述数组的类型。
interface NumberArray {
[index: number]: number;
}
const nums: NumberArray = [1, 2, 3];
2.4 混合类型
接口可以描述包含多种类型的复杂对象。
interface User {
name: string;
age: number;
skills: string[];
greet(): void;
}
2.5 类类型
接口可以描述类的结构。
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
}
2.6 可索引类型
接口可以描述动态属性的对象。
interface DynamicProps {
[key: string]: string | number;
}
const obj: DynamicProps = {
name: "Alice",
age: 25,
};
3. 接口与类型别名的区别
接口和类型别名(type
)都可以用来定义类型,但它们有一些区别:
特性 | 接口 (interface ) | 类型别名 (type ) |
---|---|---|
扩展 | 支持继承 (extends ) | 支持联合类型、交叉类型 |
合并 | 同名接口会自动合并 | 不支持合并 |
描述类型 | 主要用于对象类型 | 可以描述任意类型(对象、联合、元组等) |
实现 | 类可以通过 implements 实现接口 | 类不能实现类型别名 |
4. 总结
TypeScript 中的接口主要用于:
- 定义对象的形状。
- 提供类型检查。
- 支持代码复用和继承。
- 描述函数、数组、类等类型。
接口的核心作用是 为 JavaScript 提供静态类型检查,帮助开发者在编译时捕获错误,提高代码的健壮性和可维护性。