在 TypeScript 中,接口(Interfaces)用于定义对象的类型。它们可以描述对象的形状、类的行为契约,并允许在代码中强制执行特定的结构和类型。接口在 TypeScript 类型系统中扮演了非常重要的角色,提供了灵活的方式来定义数据和方法的类型。
定义接口
接口的基本语法如下:
interface Person {
name: string;
age: number;
}
let john: Person = {
name: "John",
age: 30
};
// 下面的赋值会导致错误,因为对象不符合接口的定义
// let jane: Person = {
// name: "Jane"
// // Error: Property 'age' is missing in type '{ name: string; }' but required in type 'Person'.
// };
可选属性
接口中的属性可以是可选的,通过在属性名后面加上 ? 标记来实现。
interface Person {
name: string;
age?: number;
}
let jane: Person = {
name: "Jane"
}; // OK,因为 `age` 是可选的
只读属性
接口中的属性还可以是只读的,通过使用 readonly 修饰符来指定。这意味着这些属性一旦被赋值就不能再修改。
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
// p1.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.
函数类型
接口也可以用来描述函数类型。定义一个具有调用签名的接口:
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string): boolean {
return source.indexOf(subString) !== -1;
};
类类型
接口可以用来强制类遵循某种结构。在接口中定义类应有的方法和属性,然后使用 implements 关键字使类实现该接口:
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) {
this.currentTime = new Date();
}
setTime(d: Date) {
this.currentTime = d;
}
}
扩展接口
接口可以通过 extends 关键字进行扩展,这样可以从现有接口里复制成员,创建新接口。
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
let square: Square = {
color: "blue",
sideLength: 10,
penWidth: 5.0
};
混合类型
接口不仅可以描述对象的形状,还可以描述那些既有属性又有方法的对象。例如,一个对象可以同时作为函数和拥有一些属性:
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = (function (start: number) {}) as Counter;
counter.interval = 123;
counter.reset = function () {};
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
接口继承类
接口也可以继承类类型,这意味着接口不仅会继承类的成员,还会继承其私有和受保护的成员:
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class Button extends Control implements SelectableControl {
select() {}
}
class TextBox extends Control {
select() {}
}
// Error: Class 'Image' incorrectly implements interface 'SelectableControl'.
// Types have separate declarations of a private property 'state'.
// class Image implements SelectableControl {
// private state: any;
// select() {}
// }
在这个例子中,SelectableControl 继承了 Control,因此只有Control 的子类才能实现 SelectableControl 接口。
通过接口,TypeScript 提供了一种强大的方式来定义和约束对象、函数和类的类型,确保代码的一致性和可靠性。