Interface接口
接口 · TypeScript中文网 · TypeScript——JavaScript的超集
TS中,接口用于定义和约束对象的结构,定义对象的形状(Shape)
类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
typescript
// 定义一个接口
interface Person {
firstName: string;
lastName: string;
age: number;
}
// 使用接口来约束对象的形状
let person: Person = {
firstName: "John",
lastName: "Doe",
age: 30
};
- 每一个属性的值必须一一对应到接口的属性类型
- 不能有多的属性,也不能有少的属性,包括直接在对象内部声明,或是 obj1.other = 'xxx' 这样属性访问赋值的形式
可选属性
typescript
// 注意,接口分号结尾
interface Car {
make: string;
model: string;
year?: number; // 可选属性
}
let myCar: Car = {
make: "Toyota",
model: "Camry"
};
只读属性
一些对象属性只能在对象刚刚创建的时候修改其值。 readonly是作为对象的属性使用!!! readonly => 防止对象的属性被再次赋值。
typescript
interface Point {
readonly x: number;
readonly y: number;
}
// 赋值后,x和y再也不能被改变了。
const point: Point = { x: 10, y: 20 };
point.x = 30; // Error:
// Cannot assign to 'x' because it is a read-only property.
额外属性检查
typescript
interface Person {
name: string;
age: number;
}
let john: Person = {
name: "John",
age: 30,
// 错误: 对象文字可以只指定已知属性,并且 'gender' 不在类型 'Person' 中。
gender: "male"
};
TypeScript 报告了一个错误,因为 gender 属性不在 Person 接口中定义。为了解决这个问题,有几种方法:
使用类型断言
typescript
let john: Person = {
name: "John",
age: 30,
gender: "male" // 使用类型断言,告诉编译器你知道这是安全的
} as Person;
添加字符串索引签名
typescript
interface Person {
name: string;
age: number;
[key: string]: any; // 添加索引签名,允许包含额外的属性
}
let john: Person = {
name: "John",
age: 30,
gender: "male"
};
// 它允许将任意类型的属性添加到对象中。
// 使用类型断言或类型别名可能更灵活,具体取决于你的需求和设计决策。
函数类型的接口
在 TypeScript 中,可以使用函数类型的接口来定义函数的形状,以明确函数参数和返回值的类型
参数列表里的每个参数都需要名字和类型。
typescript
// 定义一个函数类型的接口
interface MathOperation {
(x: number, y: number): number;
}
// 使用函数类型接口来定义一个加法函数
let add: MathOperation = function(x, y) {
return x + y;
}
// 使用函数类型接口来定义一个乘法函数
let multiply: MathOperation = function(x, y) {
return x * y;
}
类类型的接口-实现类-implements
可以使用接口(interface)来描述类的类型。通过接口,可以定义类应该具有哪些属性和方法。
typescript
// 定义一个接口
interface Animal {
name: string;
makeSound(): void;
}
// 实现接口的类
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log("Woof! Woof!");
}
}
// 实例化类
const myDog: Animal = new Dog("Buddy");
// 调用方法
myDog.makeSound();
Animal 是一个接口,它规定了类应该具有 name 属性和 makeSound 方法。然后,Dog 类实现了这个接口,确保它有这两个属性和方法。。
继承接口-extends
接口继承允许你创建一个新接口,该接口包含已有接口的所有成员,同时可以添加新的成员或覆盖现有成员。
typescript
// 基础接口
interface Shape {
color: string;
}
// 继承基础接口并添加新的属性
interface Square extends Shape {
sideLength: number;
}
// 使用继承后的接口
const square: Square = {
color: "red",
sideLength: 10,
};
继承多个接口,逗号隔开
一个接口可以继承多个接口,创建出多个接口的合成接口。
typescript
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
// Square继承了Shape,PenStroke两个接口
interface Square extends Shape, PenStroke {
sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
type 与 interface
很多同学更喜欢用 type(Type Alias,类型别名)来代替接口结构描述对象,更推荐的方式是,interface 用来描述对象、类的结构,而类型别名用来将一个函数签名、一组联合类型、一个工具类型等等抽离成一个完整独立的类型。但大部分场景下接口结构都可以被类型别名所取代,因此,只要你觉得统一使用类型别名让你觉得更整齐,也没什么问题。