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

十个TypeScript开发进阶技巧

时间:2023-03-14 11:58:45 科技观察

在使用了一段时间的Typescript之后,深感Typescript在大中型项目中的必要性。许多编译时错误,例如烦人的拼写问题,都可以提前避免。而且越来越多的包在使用TS,学习它势在必行。下面是我在工作中学到的一些比较实用的Typescript技巧。今天整理出来分享给大家。希望对您有所帮助。1.keyofkeyof与Object.keys略有相似,只是keyof使用的是界面的key。接口点{x:数字;y:number;}//键入keys="x"|“y”型键=keyofPoint;假设我们有一个如下图所示的对象,我们需要使用typescript实现一个get函数来获取其属性的值。constdata={a:3,hello:'max'}functionget(o:object,name:string){returno[name]}一开始我们可能是这样写的,但是它有很多缺点:它无法确认返回类型:这将失去ts的最大类型检查功能。无法约束键:可能有错字。在这种情况下,可以使用keyof来增强get函数的类型功能。有兴趣的可以查看_.get的类型标签及其实现。functionget(o:T,name:K):T[K]{returno[name]}2.必选&部分&选择知道了keyof就可以使用了对属性做一些扩展,比如实现Partial和Pick。pick一般用在_.picktypePartial={[PinkeyofT]?:T[P];};typeRequired={[PinkeyofT]-?:T[P];};typePick={[PinK]:T[P];};interfaceUser{id:number;年龄:数字;name:string;};//等价于:typePartialUser={id?:number;年龄?:数字;名称?:字符串;}typePartialUser=Partial//等同于:typePickUser={id:number;年龄:数字;}typePickUser=Pick这些类型内置于Typescript中。3.条件类型类似于?:操作符,可以用来扩展一些基本类型。T延伸U?X:YtypeisTrue=Textendstrue?true:false//等价于typet=falsetypet=isTrue//等价于typet=falsetypet1=isTrue4.never&Exclude&Omitnever类型表示永远不会出现的值类型.结合never和条件类型可以引入许多有趣和有用的类型,例如OmittypeExclude=TextendsU?never:T;//等价于:typeA='a'typeA=Exclude<'x'|'a','x'|'你'|'z'>结合Exclude,可以介绍Omit的写法。typeOmit=Pick>;interfaceUser{id:number;年龄:数字;name:string;};//等价于:typePickUser={age:number;名称:字符串;}typeOmitUser=Omit5.typeof顾名思义,typeof表示取某个值的类型。下面的例子展示了它们的用法consta:number=3//等同于:constb:number=4constb:typeofa=4在典型的服务端项目中,我们经常需要往上下文中塞一些工具,比如作为config、logger、dbmodels、utils等,然后使用typeof。从'./logger'导入记录器从'./utils'接口导入实用程序ContextextendsKoaContect{logger:typeoflogger,utils:typeofutils}app.use((ctx:Context)=>{ctx.logger.info('hello,world')//会返回错误,因为这个方法没有暴露在logger.ts中,这样可以最大限度地减少拼写错误ctx.loger.info('hello,world')})6.在这之前,我们先来看在一个koa的errorhandling过程中,就是集中errorhandling和识别代码的过程。app.use(async(ctx,next)=>{try{awaitnext();}catch(err){letcode='BAD_REQUEST'if(err.isAxiosError){code=`Axios-${err.code}`}elseif(errinstanceofSequelize.BaseError){}ctx.body={code}}})在err.code中,它会编译错误,属性'codedoesnotexistontype'Error'.ts(2339)".在这种情况下,你可以使用asAxiosError或asany来避免错误,但是转换不够友好!}`}在这种情况下,您可以使用is来确定值的类型。functionisAxiosError(error:any):errorisAxiosError{returnerror.isAxiosError}if(isAxiosError(err)){code=`Axios-${err.code}`}这个在GraphQL源码中有很多用法识别类型。导出函数isType(type:any):typeisGraphQLType;导出函数isScalarType(type:any):类型为GraphQLScalarType;导出函数isObjectType(type:any):类型为GraphQLObjectType;exportfunctionisInterfaceType(type:any):typeisGraphQLInterfaceType;7.interface&type接口和类型有什么区别?可以参考这里:https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescriptinterface和type的区别很小,比如下面两种写法就差不多了。接口A{a:数字;b:数字;};类型B={a:数字;b:number;}interface可以组合如下,type只能用&class链接。interfaceA{a:number;}interfaceA{b:number;}consta:A={a:3,b:4}8.Record&Dictionary&Many这些语法糖是从lodash类型源码中学习到的,是在工作场所经常使用。typeRecord={[PinK]:T;};interfaceDictionary{[index:string]:T;};interfaceNumericDictionary{[index:number]:T;};constdata:Dictionary={a:3,b:4}9.MaintainconsttablewithconstenumUseobjectstomaintainconstconstconstsconstTODO_STATUS{TODO:'TODO',DONE:'DONE',DOING:'DOING'}//用constenum维护常量constenumTODO_STATUS{TODO='TODO',DONE='DONE',DOING='DOING'}functiontodos(status:TODO_STATUS):Todo[];todos(TODO_STATUS.TODO)10.VSCode技巧与Typescript命令有时使用VSCode,用tscdo编译时出现的问题不符合VSCode提示的问题。找到项目右下角的Typescript字样,右边显示的是版本号,可以点进去,选择UseWorkspaceVersion,意思是永远和项目依赖的typescript版本一样.或者编辑.vs-code/settings.json{"typescript.tsdk":"node_modules/typescript/lib"}总之,TypeScript增加了代码的可读性和可维护性,让我们的开发更加优雅。如果你觉得我今天的内容对你有用,请记得点赞,关注我,把这篇文章分享给你的朋友,说不定能帮到他。最后感谢阅读,祝编程愉快!