当前位置: 首页 > Web前端 > JavaScript

一言以蔽之,TypeScript的接口

时间:2023-03-27 12:27:40 JavaScript

●通过前两章的学习,我们对TS基本有了一个了解●但是我们会发现好像少了一些关于类型限制的内容●我们会继续学习这一章的接口●初学者一听这个名字,可能不太好理解●接触过前后端交互的人可能会被这个名字搞糊涂,也很容易混淆●不过,不要纠结,什么都忘了你有直接的,只是一个名字●就像老婆饼这个东西,老婆在哪里,只是一个名字●那这个接口是干什么用的?○其实只是用来限制非基础数据的一种类型限制方法●我们回顾一下之前的类型限制,发现○对于对象、函数、类等,没有很好的限制内容的方法○是真的没有,不是○接口是第一次接口之一●看下面的例子让用户:{name:string}={}●所以这段代码会提示错误●那么我们需要修改代码。赋值时,需要有name属性。letuser:{name:string}={name:'千峰大前端'}那么就没有问题●继续看下一个例子letuser:{name:string}={name:'千峰大前端'}letperson:{name:string}={name:'前端培训界的佼佼者'}我们会发现user变量和person变量的类型完全一样的内容使用限制○但是我需要一个一个的写吧○按照我们程序员的懒惰,为什么不能把这个东西写一遍呢?○一定可以●这个东西叫接口○我们可以把这个叫做类型限制,拿出来写成接口○用起来方便很多●写成接口的形式interfaceInfo{name:string}letuser:Info={name:'前锋大前端'}letperson:Info={name:'前端培训界的领军人物'}○interface:TS中定义接口的关键字○Info:The接口名称(建议首字母大写)●是不是突然清楚接口的各种属性基本接口属性●是接口中的各种属性受数据类型限制interfaceInfo{name:stringage:numbergender:booleanhobby:string[]}●该接口为基础接口限制○必须包含name属性,类型必须是string○必须包含age属性,类型必须是number○必须包含性别属性,必须是boolean类型○必须包含爱好属性,是字符串数组。可选属性●我们可以设置一些属性optionalinterfaceInfo{name:stringage:numbergender:booleanhobby:string[]city?:string}这里设置了一个可选属性。city属性是可选的。如果添加city属性,则必须是字符串类型的只读属性。我们还可以设置一些不允许修改的属性。当我们需要在接口中写入属性时,使用readonly关键字interfaceInfo{name:stringage:numbergender:booleanhobby:string[]city?:stringreadonlynationality:string}定义了这个之后,extra属性就不能修改了在定义了国籍属性值之后。说到这里你会发现一个问题○就是如果我用一个接口来限制一个数据,那么我必须写所有可能的属性○但是如果我只能确定一些属性而其他的不确定怎么办?●这时候,可以使用附加属性interfaceInfo{name:stringage:numbergender:booleanhobby:string[]city?:stringreadonlynationality:string[props:string]:any}表示,除了这里已经列出的属性,你也可以添加其他键值对○但是键必须是字符串类型○值可以是任何类型●这个额外的属性其实是不推荐的○第一:我们最好掌握数据我们自己写的类型限制○第二:这样,我们限制的意义不是很大。Indexed接口●Indexed接口一般使用接口来约束一个数组interfaceStringArray{[index:number]:string}先分析一下这个接口○使用额外的属性○可以添加任意数量的属性○但是key必须是数字类型■如果是object数据结构,那么key只能是string类型■Array数据类型,key是number类型○value必须是字符串●所以这个接口被限制为字符串组成的数组.其实这就相当于我们限制数组的方式。interfaceStringArray{[index:number]:string}letlist:StringArray=['hello']//等价于letlist2:string[]=['world']functioninterface●想一想,其实就是定义一个函数无非就是两部分○参数○返回值●所以一个函数接口就是限制一个函数的参数和返回值就可以了。interfaceSearchFunc{(x:number,y:string):string}分析一波○这个限制了需要两个参数,一个是number类型,一个是string类型○也限制了返回值必须是是一个string类型○那么这个数据类型一定是函数●但是这种接口一般用于限制函数表达式○不适用于声明式函数interfaceSearchFunc{(x:number,y:string):string}constfn:SearchFunc=function(x,y){returnx+y}接口继承●接口也可以继承●同样使用extends关键字interfacePerson{name:stringage:18}//Student接口继承自Person接口interfaceStudentextendsPerson{classRoom:number}类接口●为什么把类接口放在最后,因为观察和分析类很复杂●先写个简单的吧类分析classStudent{constructor(name,age){this.name=namethis.age=age}sayHi(){console.log(`Hello,Mynameis${this.name}`)}}我们来看看如何限制一个类○限制调用必须和new关键字一起使用○类中有一个构造函数,需要接受参数,限制返回的实例是一个什么样的对象○我们调用这个类有多少个参数通过了,它们是什么类型?类的原型上有多少方法?需要那么多维度来限制一个类类型的数据类接口。首先,我们要学习一个新的接口规范,叫做Class接口●Class接口专门用于类●先来看一下//对象接口,限制实例对象接口StudentInstance{name:stringage:number}//类接口,限制构造函数interfaceStudentConstructor{//构造函数返回值必须是符合StudentInstance实例限制的对象new(name:string,age:number):StudentInstance}●类要使用接口,需要用implements关键字classStudentimplementsStudentConstructor{constructor(name:string,age:number){this.name=namethis.age=age}}看起来很好,也很简单●但是写完之后,我发现都错了●我给你分析一下○StudentConstructor接口,看好像是类接口,其实只是限制了new关键字和返回值类型。不能说它是一个类,它更像是一个函数,所以我们去限制一个类显然不好。○Student类不是A函数是类,里面的constructor是构造函数,那么这个构造不调用controller的时候,没有instance,所以不能合理的加上name和age属性●都是问题,那怎么办●这个时候如果想把所有的限制都做的比较好,我们需要用到工厂函数○并且还需要两个接口○一个受限的实例对象○一个受限的构造函数不要担心加TS限制,先把类写成工厂模式//定义工厂函数//functioncreateStudent(class,parameter1,parameter2){}functioncreateStudent(ctro,name,age){returnnewctro(name,age)}●也就是说,我们要把类放到工厂函数中调用。我们的工厂函数需要接受一个类,并且还要接受这个类需要的参数○在工厂函数中实例化,然后返回●接下来,我们可以添加接口限制//实例接口,限制实例对象接口StudentInstance{name:stringage:numbersayHi():void}//类接口,限制构造器接口StudentConstructor{new(name:string,age:number):StudentInstance}//工厂函数functioncreateStudent(ctro:StudentConstructor,name:string,age:number):StudentInstance{returnnewctro(name,age)}○工厂函数的ctro参数必须是满足StudentConstructor接口的类。工厂函数的返回值必须是满足StudentInstance接口的实例对象。类的实例对象的成员比较多,但是如果成员过多就不行了。因为工厂函数只能接受这些数据。如果成员过多,调用工厂函数时会出错。最后写类//实例接口,限制实例对象接口StudentInstance{name:stringage:numbersayHi():void}//类接口,限制构造函数接口StudentConstructor{new(name:string,age:number):StudentInstance}//工厂函数functioncreateStudent(ctro:StudentConstructor,name:string,age:number):StudentInstance{returnnewctro(name,age)}//定义类classPersonimplementsStudentConstructor{name:stringage:numberconstructor(name:string,age:number){this.name=namethis.age=age}sayHi():void{}}//开始使用lets1=createPerson(同学,'千峰大前端',10)console.log(s1)●这个时候就完成了一个真正的类限制●确实很麻烦,所以我们在开发过程中比较少进行类限制限制●因为类本身就是一个限制