TypeScript-接口类型
小开开 2020-12-07 17:15:59 2020-12-07 262 0
对象类型
对象类型是TypeScript的类型系统中最复杂也是最重要的类型,对象类型主要用来描述复杂数据类型:
// 声明一个值为对象字面量let man = {name: 'joye', age: 30};// 等价于let man: {name: string; age: number} = {name: 'joye', age: 30};
在上例第一条语句中,实际上变量 man
会被自动推导为类型 {name: string; age: number}
,它描述了一个对象具有字符串类型的 name
属性和数字类型的 age
属性 。
感谢wenxudong090161 提醒:属性之间可以用分号
参考Issues #1。为了保持代码的可读性和规范,建议声明的描述中采用;
分隔,也可以用逗号,
分隔,甚至可以只用换行符分隔!;
分隔,以此来区分注解和值
接口类型
对象类型是匿名的接口类型,对象类型没有名字,接口类型有名字。接口类型相当于为对象类型声明了一个别名:
// 定义接口类型Personinterface Person { name: string; age: number;}// 声明变量 man 为 Person 接口类型let man: Person = {name: 'joye', age: 30};
上述语句完全等价于:
let man: {name: string; age: number} = {name: 'joye', age: 30};
本教程后续章节将统一术语:接口代表接口类型,匿名接口代表对象类型
可选属性
接口的属性是可选的,可选属性类似于函数的可选参数:属性名后添加问号?
即可
interface Person { name: string; age: number;}// 错误,缺少必选属性 age// error TS2322: Type '{ name: string; }' is not assignable to type 'Person'. // Property 'age' is missing in type '{ name: string; }'.let man: Person = { name: 'joye'};
将 age
改成可选属性:
interface Person { name: string; // 注意此处的问号,age此时为可选属性 age?: number; }// 正确let man: Person = { name: 'joye'};
只读属性
可以通过在属性名前添加 readonly
关键字来指定只读属性,只读属性只能在创建的时候对其赋值,一旦创建完成,就再也不能更改:
interface Person { // 声明name为只读 readonly name: string; age: number;}// 创建时对只读属性赋值let man: Person = { name: 'joye', age: 30}// 错误,只读属性的值不能更改// error TS2540: Cannot assign to 'name' because it is a constant or a read-only propertyman.name = 'mike';// 正确,非只读属性的值可以更改man.age = 31;
接口的应用
接口最重要的作用在于描述一个复杂值的外形,通常情况下,接口可以描述:
- 对象字面量
- 函数
- 可索引值
- 类
描述对象字面量
前面的 Person
接口就是描述对象字面量的例子,此处不再重复举例。
对象字面量的类型匹配非常让人迷惑,请看下面的例子:
interface Person { name: string; age: number;}// 定义一个对象字面量malelet male = { name: 'joye', age: 30, gender: 'male'};// 正确,male包含Person接口的所有属性let man: Person = male;
在上面的例子中,对象字面量 male
被编译器推导为匿名接口类型,相当于:
// 声明male为匿名接口let male: { name: string; age: number; gender: string;};// 对male赋值male = { name: 'joye', age: 30, gender: 'male'};
匿名接口类型包含了 Person
接口的所有属性 name
、age
,编译器认为类型匹配,通过类型检查。然而:
interface Person { name: string; age: number;}// 直接将对象字面量赋值给接口类型// 错误,对象字面量直接赋值检查所有属性的兼容性// error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'. // Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.let man: Person = { name: 'joye', age: 30, gender: 'male'};
请牢记:对象字面量在直接赋值的时候,编译器会检查字面量类型是否完全匹配,多一个或少一个属性都会报错。
描述函数
声明一个函数类型的多种方式:
```typescript
// 描述函数interface MyFunc { (name: string, age: number): string; }// 声明接口类型
let fn: My