今天学一个非常重要的概念-接口
接口的定义
在面向对象语言中,接口是一个很重要的概念,它是对行为的抽象,而具体如何,需要由类(class)去实现
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
一个很简单的例子
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
在上面中,我们定义了一个接口Person(接口通常是首字母大写),接着又定义了一个变量tom,
它的类型是 Person
。这样,我们就约束了 tom
的形状必须和接口 Person一致。既然说到了约束了tom的形状,也就是说定义的变量比接口少了一些属性是不被允许的,比如,你定义tom时,没有age属性,那么ts就会报错,那么我多一个sex(性别)属性呢?那也是不可以的,但是有时候我们并不希望所有的属性都和接口完全匹配,那么可以用可选属性。例如:
interface Person {
name: string;
age: number;
sex?:string
}
let tom: Person = {
name: 'Tom',
age: 25
};
现在sex就是可选了,他的含义是可以不存在,但是不允许添加未定义的属性。
那么我想要一个比较"自由"的接口该怎么定义呢?
那么就需要用到接口的任意属性了,例如:
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
[propName: string]: any; 定义了任意属性取string的值,但是需要注意的是一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集,例如:
interface Person {
name: string;
age?: number;
[propName: string]: string;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
上面例子中,任意属性的值允许是string,但是可选属性age的值却是number,nmber不是string的子类型,所以会报错,
一个接口只能定义一个任意属性,如果接口中有多个类型的属性在,则可以在任意属性中使用联合类型
interface Person {
name: string;
age?: number;
[propName: string]: string | number;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly
定义只读属性:
只读属性
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 89757,
name: 'Tom',
gender: 'male'
};
tom.id = 9527;
上面例子中,我们给id添加了readonly约束,被给他赋89757的值,然后他又被赋值了,这当然会报错,注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
感谢:ts博客