当前位置: 首页 > 科技观察

TypeScript提升幸福感的10个进阶技巧

时间:2023-03-12 09:35:57 科技观察

我使用TypeScript已经一年了,项目中使用的技术是Vue+TypeScript。深感TypeScript在中大型项目中的必要性,尤其是生命周期比较,在长大型项目中更应该使用TypeScript。以下是我在工作中经常使用的TypeScript技巧。1.评论:/***/形式的评论可以用来标记提示TS类型,小编会有更好的提示:/**Thisisacoolguy.*/interfacePerson{/**Thisisname.*/name:string,}constp:Person={name:'cool'}如果你想给一个属性添加评论或者友情提醒,这是个好方法。2.接口继承和类一样,接口也可以相互继承。这允许我们将成员从一个接口复制到另一个接口,从而更灵活地将接口拆分为可重用的模块。interfaceShape{color:string;}interfaceSquareextendsShape{sideLength:number;}letsquare={};square.color="blue";square.sideLength=10;一个接口可以继承多个接口并创建多个接口合成接口。interfaceShape{color:string;}interfacePenStroke{penWidth:number;}interfaceSquareextendsShape,PenStroke{sideLength:number;}letsquare={};square.color="blue";square.sideLength=10;square.penWidth=5.0;3。interface&type在TypeScript中定义类型有两种方式:接口和类型别名。例如下面的Interface和Type别名的例子,除了语法不同,含义是一样的:InterfaceinterfacePoint{x:number;y:number;}interfaceSetPoint{(x:number,y:number):void;}输入aliastypePoint={x:number;y:number;};typeSetPoint=(x:number,y:number)=>void;两者都可以扩展,但语法不同。另外,请注意接口和类型别名并不相互排斥。接口可以扩展类型别名,反之亦然。接口扩展interfacePartialPointX{x:number;}interfacePointextendsPartialPointX{y:number;}类型别名扩展类型aliastypePartialPointX={x:number;};typePoint=PartialPointX&{y:number;};接口扩展类型aliastypePartialPointX={x:number;};interfacePointextendsPartialPointX{y:number;}类型别名扩展interfaceinterfacePartialPointX{x:number;}typePoint=PartialPointX&{y:number;};它们之间的区别可以看下图或者TypeScript:InterfacesvsTypes。所以巧妙地使用界面和类型并不容易。如果你不知道该用什么,记住:如果你可以使用接口,就使用接口,如果不能,就使用类型。4.typeoftypeof运算符可用于获取变量或对象的类型。我们一般先定义类型,然后使用:interfaceOpt{timeout:number}constdefaultOption:Opt={timeout:500}有时可以反过来:constdefaultOption={timeout:500}typeOpt=typeofdefaultOption当一个接口总是有一个字面初始value,可以考虑这种写法,减少重复代码,至少减少了两行代码,哈哈~5.keyofTypeScript允许我们遍历某类属性,通过keyof运算符提取其属性的名称。keyof运算符是在TypeScript2.1中引入的。该运算符可用于获取某一类型的所有键,其返回类型为联合类型。keyof和Object.keys有点类似,只是keyof取的是接口的key。constpersion={age:3,text:'helloworld'}//typekeys="age"|"text"typekeys=keyofPoint;在写获取对象中属性值的方法时,一般人可能会这样写人格,'文本');但是会提示错误,因为对象中没有预先声明的key。当然如果把o:object改成o:any也不会报错,但是得到的值会没有类型,变成any。这时候可以使用keyof来加强get函数的类型功能。有兴趣的同学可以看看_.get的类型标识,实现函数get(o:T,name:K):T[K]{returno[name]}6。找到typeinterfacePerson{addr:{city:string,street:string,num:number,}}需要用到addr类型的时候,除了带上typeinterfaceAddress{city:string,street:string,num:number,}interfacePerson{addr:Address,}也可以是Person["addr"]//ThisisAddress。例如:constaddr:Person["addr"]={city:'string',street:'string',num:2}在某些情况下,后者会使代码更清晰易读。7.Findtype+generics+keyof泛型(Generics)是指在定义函数、接口或类时,不事先指定具体类型,而是在使用时指定类型的特性。interfaceAPI{'/user':{name:string},'/menu':{foods:string[]}}constget=(url:URL):Promise=>{returnfetch(url).then(res=>res.json());}get('');get('/menu').then(user=>user.foods);8.Vue组件ref中经常使用类型断言来获取子组件的属性或方法,但往往无法推断出有哪些属性和方法,就会报错。子组件:父组件:因为this.$refs.helloRef是未知类型,将报告一条错误消息:只需进行类型断言:print(){//consthelloRef=this.$refs.helloRef;consthelloRef=this.$refs.helloRefasany;console.log("helloRef.msg:",helloRef。味精);//helloRef.msg:WelcometoYourVue.js+TypeScriptApp}但是当类型断言是any的时候就不好了。知道具体的类型就写具体的类型,否则引入TypeScript9似乎没有意义。显式泛型$('button')是一个DOM元素选择器,但是返回值的类型只能在运行时确定。除了返回any,还可以function$(id:string):T{return(document.getElementById(id))asT;}//不确定输入的类型//constinput=$('input');//Tellmewhatelementitis.constinput=$('input');console.log('input.value:',input.value);函数泛型不一定必须自动推导类型,有时明确指定类型会很好。10.DeepReadonlyreadonly标记的属性只能在声明时或类的构造函数中赋值。之后不能更改(即只读属性),否则将抛出TS2540错误。和ES6中的const很像,但是readonly只能用在类中的属性(或者TS中的接口)上,相当于一个只有getter没有setter的属性的语法糖。以下实现深度声明只读类型:typeDeepReadonly={readonly[PinkeyofT]:DeepReadonly;}consta={foo:{bar:22}}constb=aasDeepReadonlyb.foo。bar=33//不能赋值给'bar'因为它是只读属性.ts(2540)