声明接口需要使用 interface 关键字。
interface User {
?name: string;
?age: number;
}
使用接口约束对象的类型。
const user: User = {
?name: "张三",
?age: 20,
};
使用接口约束函数的类型。
interface Sum {
(n: number, m: number): number;
}
?
const sum: Sum = function (a, b) {
?return a + b;
};
使用接口约束类的成员。
interface Calendar {
?name: string;
?addEvent(): void;
?removeEvent(): void;
}
?
class GoogleCalendar implements Calendar {
?name: string = "test";
?addEvent(): void {}
?removeEvent(): void {}
}
TypeScript 接口检查是宽松的,当变量满足了接口规范以后,即使变量中存在接口规范以外的属性也是可以的。
interface User {
?name: string;
?age: number;
}
?
let user: User = {
?name: "张三",
?age: 20,
};
?
let someone = {
?name: "李四",
?age: 50,
?sex: "男",
};
?
user = someone;
interface Reportable {
?summary(): void;
}
?
function printSummary(item: Reportable): void {
?item.summary()
}
?
const person = {
?name: "张三",
?summary() {
console.log(`您好, 我的名字叫${this.name}`);
},
};
?
printSummary(person);
对于宽松的接口检查政策字面量是个例外,也就是说对于字面量的接口类型检查是严格的,不能出现接口规范以外的其他属性。
interface User {
?name: string;
?age: number;
}
?
// ?
const user: User = { name: "张三", age: 20 };
?
// ?
// 不能将类型"{ name: string; age: number; sex: string; }"分配给类型"User"
// 对象字面量只可以指定已知属性, "sex"不在类型"User"中
const another: User = { name: "李四", age: 40, sex: "男" };
interface Reportable {
?summary(): void;
}
?
function printSummary(item: Reportable): void {
?item.summary();
}
?
// ?
// 类型"{ name: string; summary(): void; }"的参数不能赋给类型"Reportable"的参数。
// 对象字面量只可以指定已知属性, "name"不在类型"Reportable"中。ts(2345)
printSummary({
?name: "张三",
?summary() {
? ?console.log(`您好, 我的名字叫${this.name}`);
},
});
那么如何绕过字面量严格类型检查模式呢?
// 使用类型断言
interface User {
?name: string;
?age: number;
}
?
const another: User = { name: "李四", age: 40, sex: "男" } as User;
// 使用索引签名
interface User {
?name: string;
?age: number;
[key: string]: string | number;
}
?
const another: User = { name: "李四", age: 40, sex: "男" };
接口具有继承特性即接口与接口之间可以存在继承关系,而且一个接口可以继承多个接口。
// 接口继承示例
interface Sizes {
?sizes: string[];
?getAvailableSizes(): string[];
}
?
interface Shape {
?color: string;
}
?
interface Pizza extends Sizes, Shape {
?name: string;
}
?
let pizza: Pizza = {
?name: "张三",
?color: "skyblue",
?sizes: ["large", "small"],
?getAvailableSizes() {
? ?return this.sizes;
},
};
在继承了接口以后可以对被继承接口中的属性进行重写,但是重写的类型一定要在原有类型的范围以内。
interface User {
?// name: string | number | boolean;
?name: any;
?age: number;
}
?
interface MyUser extends User {
?name: boolean;
}
接口具有声明合并特性,即多个相同名称的接口会自动合并。
interface Box {
?height: number;
?width: number;
}
?
interface Box {
?scale: number;
}
?
let box: Box = { height: 5, width: 6, scale: 10 };
interface GetMessage {
(id: number): Message | undefined;
(type: MessageType): Message[];
}
?
const getMessage: GetMessage = (query: any): any => {
?if (typeof query === "number") {
? ?return data.find((message) => message.id === query);
} else {
? ?return data.filter((message) => message.type === query);
}
};