说明
在面向对象语言中,接口是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类去实现。
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。(也就是对象里面的属性或方法进行描述)
基础用法
使用interface
关键字声明接口
interface User {
name: string,
age: number,
getName: () => string
}
let person: User = {
name: 'fufu',
age: 20,
getName: function(): string {
return this.name
}
}
定义只读属性
使用readonly
关键字限制接口中的参数是只读 ,使用该接口的对象只有在第一次赋值的时候可以对可读属性进行赋值操作。
interface User {
readonly name: string,
readonly age: number
}
let person: User = {
name: 'fufu', age: 20}
person.name = 'dandan' // Cannot assign to 'name' because it is a read-only property.
有时候我们会想到如果我们定义一个只读的接口,为什么不直接使用const声明一个对象呢?
readonly
是’TS’ 在接口提出,只针对接口中的参数赋值后就禁止更改,而const
是
es6 提出的针对变量,不让变量进行更改。其次const声明一个对象只是内存地址不允许修改,但是里面的属性是可以修改的。
最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用const,若做为属性则使用readonly。
定义不确定属性
很多时候我们并不确定对象里面有没有该属性,这个时候可以使用?
关键字进行说明
interface User {
name?: string,
age: number
}
let person: User = {
age: 20}
索引签名
那如果一个对象属性很多,且都是不确定的情况下,我们应该如何声明呢?如果使用?
则需要将所有可能出现的属性定义出来,这肯定是不合理的。我们可以使用索引签名的方式进行定义。
interface Person {
name: string;
age: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
age: 25,
height: 170
};
定义数组
接口除了用于定义对象结构外,还可以用于数组的定义,类似于元组。
interface arr {
0: number,
1: string
}
let arr1: arr = [1, '1']
arr1.push(1) // Property 'push' does not exist on type 'arr'.
当然他肯定与元组也是有区别的。元组虽然是定义已知类型和和长度的数组,但是使用push
依旧可以改变数组长度。使用interface
即使使用push
也依旧无法修改数组长度。
继承
接口是可以继承与被继承的,并且继承可以同时继承多个接口。
interface A {
name: string
}
interface B {
age: number
}
interface User extends A , B {
gender: boolean
}
let user:User = {
age: 20,
name: 'fufu',
gender: true
}
注意如果在继承过程中发现相同属性但却类型不同,会判断当前类型是否兼容之前的类型
interface A {
name: string
}
interface B {
gender: boolean,
}
interface User extends A , B {
gender: any, //如果设置为string则报错
age: number
}
let user:User = {
age: 20,
name: 'fufu',
gender: '1'
}