前言
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。
什么是接口
在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
简单案例
js
interface Preson {
name: string,
age: number,
sex: string
}
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男'
}
分析
1.定义接口Preson,定义三个参数,并定义对应的类型
2.定义对象obj,指定接口类型Preson,那么obj的参数和类型就必须按照接口定义的一致去写
多一些属性和少一些属性都是不允许的,可以看到,在定义的时候,如果和接口的形状不一致,编译器就会给我们提示。
可选属性
有时候我们希望不和接口定义的形状完全一致,那么我们可以在接口定义是使用可选属性
js
interface Preson {
name: string,
age: number,
sex?: string
}
let obj: Preson = {
name: 'Jack Yang',
age: 18
}
或者
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男'
}
分析
此时name和age属性是必须的,sex属性变为可选
此时也不允许添加未定义的属性
任意属性
有时候我们需要接口有任意的属性,那么我们可以这样去定义.
js
interface Preson {
name: string,
age: number,
sex?: string,
[propName:string]: any
}
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男',
length: 180
}
分析
[propName:string]:定义了任意属性取string类型的值。即length为string值,180取任意值
any:定义任意属性取任意类型值
注意
propName:取之为string或者number
一旦定义的任意属性,那么可选属性和必选属性都必须是它类型的子类型。注意,一个接口中只能定义一个任意类型。
js
interface Preson {
name: string,
age: number,
sex?: string,
[propName:string]: string
}
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男',
length: '1'
}
Type '{ name: string; age: number; sex: string; length: string; }' is not assignable to type 'Preson'.
Property 'age' is incompatible with index signature.
Type 'number' is not assignable to type 'string'.
分析
任意属性值的类型是string,此时name和sex是string,age是number,number并不是string的子类型,所以这里会报错
解决
此时可以使用联合类型定义
interface Preson {
name: string,
age: number,
sex?: string,
[propName:string]: number | string
}
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男',
a: 2
}
只读属性
如果我们希望一个属性只在被创建的时候被定义,不允许被修改,那么我们可以使用只读属性,reldonly。类型与js中的const定义变量,一旦被定义了就不允许修改。
js
interface Preson {
name: string,
readonly age: number,
sex?: string,
[propName:string]: number | string
}
let obj: Preson = {
name: 'Jack Yang',
age: 18,
sex: '男',
a: 2
}
obj.age = 19; //Cannot assign to 'age' because it is a read-only property.
注意:制度的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候。
js
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
tom.id = 89757;
// index.ts(8,5): error TS2322: Type '{ name: string; gender: string; }' is not assignable to type 'Person'.
// Property 'id' is missing in type '{ name: string; gender: string; }'.
// index.ts(13,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
分析
第一次报错:是在对tom赋值的时候,没有给id进行赋值
第二处报错:是在tom.id赋值的时候,因为不允许给只读属性赋值
总结
- 接口的定义属性有必选,可选,任意,只读,任意值类型只能是一个,其它的可以是任意个。
- 定义类型时并不是唯一,可以使用联合类型。
- 对象的定义要和接口定义的一致,不可以出现未定义的类型值,任意值除外