编辑
2023-03-24
TypeScript
0
请注意,本文编写于 630 天前,最后修改于 612 天前,其中某些信息可能已经过时。

目录

思维导图
基本的
接口的定义
接口的应用场景
接口定义的语法
注意
Eg
接口的属性
可选属性
说明
用途
Eg
只读属性
说明
Eg
任意属性
说明
Eg
接口的分类与继承
接口的分类
对象类型接口
说明
Eg
函数类型接口
说明
语法
Eg
可索引类型接口
说明
用途
按索引签名分类
数字类型签名
字符串类型签名
类类型接口
混合类型接口
接口的继承
接口使用场景举例
Eg
情况-返回值含有未定义的字段
解决方案

思维导图

interface

基本的

接口的定义

接口是一系列抽象方法的声明,是一些抽象的方法特征的集合,这些方法都需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法

接口的应用场景

  • 在声明一个对象、函数或者类时,先定义接口,确保其数据结构的一致性
  • 约束对象、函数、以及类的结构和类型

接口定义的语法

ts
interface interface_name { }

注意

接口并不会转换为js,它只是ts的一部分

  • 定义接口要首字母大写
  • 只需要关注值的外形,并不像其他语言一样,定义接口是为了实现
  • 如果没有特殊声明,定义的变量比接口少了一些属性是不允许的,多一些属性也是不允许的,赋值的时候,变量的形状必须和接口的形状保持一致

Eg

ts
// 接口 interface users { name: string age: number deposit: string motto: () => string } var customerList: users = { name: "Li", age: 20, deposit: "20 million", motto: () => { return "Too little time" } } console.log(customerList.name) console.log(customerList.age) console.log(customerList.deposit) console.log(customerList.motto) //编译过后 var customerList = { name: "Li", age: 20, deposit: "20 million", motto: function () { return "Too little time"; } }; console.log(customerList.name); console.log(customerList.age); console.log(customerList.deposit); console.log(customerList.motto);

接口的属性

可选属性

说明

有时候接口中的属性不是必须的,有些是只在某些条件下存在,或者根本不存在
通过?形式告诉编译器此变量可选

用途

  • 可以对可能存在的属性进行预定义
  • 可以捕获引用了不存在的属性时的错误

Eg

可选属性

只读属性

说明

通过属性名前加上readonly设置对象属性在对象刚创建时修改其值,在此之后便无法在此修改

Eg

ts
interface users { readonly name: string readonly age: number readonly deposit: string motto?: () => string } ......

只读属性

任意属性

说明

可以允许接口允许有任意的属性,使用中括号[属性名:类型]包裹属性名

Eg

interface close{ a:number, b:number, [c:string]:number, } let myClose:close={ a:1, b:2, d:4, h:5, g:9 } console.log(myClose)

接口的分类与继承

接口的分类

对象类型接口

说明

常见的接口类型

Eg

ts
interface users { name: string age: number deposit: string motto: () => string }

函数类型接口

说明

通过接口表示函数类型需要定义一个调用签名,类似于只有参数列表和返回值

语法

interface interface_name { (valueName:type):returnValueType }

Eg

以下两种写法等价

interface Calculate { add(x: number, y: number): number multiply: (x: number, y: number) => number }

可索引类型接口

说明

描述“通过索引得到”的类型,可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引返回值类型

用途

不确定接口内的参数有哪些

按索引签名分类

常见的有字符串类型索引和数字类型索引

数字类型签名

数字索引类型.jpg

字符串类型签名

Eg

interface strInterface { [index:string]:string }

同时使用两种类型时,数字索引签名的返回值必须是字符串索引签名返回值类型的子类型

ts
//字符串类型 //动物类 class Animal { "name": string } //狗类是动物类的子类 class Dog extends Animal { "breed": string } // 同时出现字符串类型和数字类型 interface NotOkay { [x: number]: Dog [x: string]: Animal }

类类型接口

使用implements关键字来确保兼容性,接口只能含有抽象方法和成员属性,实现类中必须实现接口中所有的抽象方法和成员属性
接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员

interface AnimalInterface { name: string eat(m: number): string } class Dog implements AnimalInterface { name: string; constructor(name: string){ this.name = name } eat(m: number) { return `${this.name}吃肉${m}分钟` } }

混合类型接口

一个对象具有多种类型

ts
//声明一个接口,如果只有 (start: number): string //一个成员,那么这个接口就是函数接口,同时还具有其他两个成员,可以用来描述对象的属性和方法,这样就构成了一个混合接口 interface Counter { (start: number): string; interval: number; reset: ()=>number; } //创建一个 getCounter() 函数,它的返回值是 Counter 类型的 function getCounter(): Counter { let counter = function (start: number) {} as Counter; /* 通过类型断言,将函数对象转换为 Counter 类型,转换后的对象不但实现了函数接口的描述 ,使之成为一个函数,还具有interval属性和reset()方法。断言成功的条件是, 两个数据类型只要有一方可以赋值给另一方,这里函数类型数据不能赋值给接口类型的变量, 因为它不具有interval属性和reset()方法 */ counter.interval = 123; counter.reset = ()=>3; return counter; } let c = getCounter(); c(10); console.log(c(10)) console.log(c.reset()) c.interval = 5.0 console.log(c.interval)

接口的继承

一个接口可以继承多个接口,创建出多个接口的合成接口

通过extends继承,若需要继承多个接口,只需要继承时使用逗号分隔开接口名称

ts
interface Shape { color: string; } // Square继承Shape interface Square extends Shape { sideLength: number; } // 继承多个接口 interface user entends user,age { } let square = {} as Square; square.color = "blue";// 继承了 Shape 的属性 square.sideLength = 10; console.log(square.color, square.sideLength)

接口使用场景举例

Eg

//定义List接口 规定对应包含哪些参数以及参数类型 interface List {id: number;name: string;age: number;} //定义Result接口 规定其中包含data参数,参数类型为List构成的数组 interface Result { data: List[]// data类型为List构成的数组 } function render(result: Result) { result.data.forEach((value) => { console.log(value.id, value.name) }) } //假设将返回值赋值给result let result = { data: [ {id: 1, name: 'A', age: 18,sex:0}, {id: 2, name: 'B', age: 18} ] } render(result)

情况-返回值含有未定义的字段

使用注意点1

解决方案

  1. 将返回值直接赋值给一个变量,然后使用变量,此时TS就允许包含接口中未定义的值

  2. 通过类型断言
    尖括号方式的类型断言在React中会产生歧义,推荐采用as方式的类型断言

// render(<Result>{ // data: [ // { id: 1, name: "A", age: 18, sex: 0 }, // { id: 2, name: "B", age: 18 }, // ], // }); render({ data: [ { id: 1, name: "A", age: 18, sex: 0 }, { id: 2, name: "B", age: 18 }, ], } as Result);
  1. 在接口中添加字符串索引类型签名 在上述Eg中的List接口添加字符串所以类型签名且设置返回值为any
interface List { id: number; name: string; age: number; [index:string]:any } ... render({ data: [ { id: 1, name: "A", age: 18, sex: 0 }, { id: 2, name: "B", age: 18 }, ], });

本文作者:RKLS

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!