Vue2.5+迁移到Typescript指南为什么要迁移到TypescriptJavascript本身是一种动态的弱类型语言。此功能导致Javascript代码中出现大量UncaughtTypeError错误。无论是调试还是在线代码稳定性都带来了很多负面影响。Typescript提供了静态类型检查,这样很多类型错误在写的时候就已经发现了,不会带到测试阶段。同时,Javascript可以在不定义模型的情况下使用对象。有些人喜欢这种灵活性。诚然,这样的语法在模型不复杂的时候可以快速开发出需要的功能,但是一旦模型庞大,就很难找到需要的属性值。不知道从哪里开始。在Typescript中,我们需要使用TS中的接口类型来定义模型,然后才能调用它的属性值,所以Typescript大大提高了代码的可读性。可行性因为TypeScript是JavaScript的超集,所以TypeScript不会阻止JavaScript运行,即使出现类型错误,这可以让你的JavaScript逐渐迁移到TypeScript。所以你可以慢慢地进行迁移,一次一个模块,选择一个模块,将.js文件重命名为.ts,在代码中添加类型注释。完成此模块后,选择下一个模块。如何将已有的Vue项目迁移到Typescript安装依赖Vue官方提供了一个库Vue-class-component,可以让我们使用Ts的类声明方式编写Vue组件代码。Vue-property-decorator提供了一种基于Vue-class-component编写代码的方式。首先我们需要在package.json中引入这两个依赖。我的项目是基于vue-cli@3.X创建的,我还需要在项目中引入@vue/cli-plugin-typescripttypescript两个依赖来完成Typescript的编译。配置tsconfig.json在项目根目录新建tsconfig.json,引入如下代码{"compilerOptions":{"target":"esnext","module":"esnext","strict":true,"jsx":"preserve","importHelpers":true,"moduleResolution":"node","experimentalDecorators":true,"esModuleInterop":true,"allowSyntheticDefaultImports":true,"sourceMap":true,"baseUrl":".","noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"types":["webpack-env"],"paths":{"@/*":["./app/common/*"],"_app/*":["./app/*"],"_c/*":["./app/common/components/*"],"api/*":["./app/service/*"],"assets/*":["./app/assets/*"]},"lib":["esnext","dom","dom.iterable","scripthost"],},"include":[//这里根据你项目中的typescript填写需要编译的文件路径"app/**/*.ts","app/**/*.tsx","app/**/*.d.ts","app/**/*.vue",],"exclude":["node_modules"]}特别是现在的vue项目大多使用webpack的别名用于解析路径。tsconfig.json中需要配置path属性,这样typescript也可以识别webpack中配置的路径别名。添加全局声明文件因为vue文件在ts文件中无法识别,所以需要在项目根目录新建shims-vue.d.ts文件,添加如下代码让ts识别vue文件.importVuefrom'vue';declaremodule'*.vue'{exportdefaultVue;}自下而上的迁移因为是现有项目的迁移,不建议一开始就把main.js重命名为main.ts,对于大多数Vue项目,main.js引入了太多的依赖项。我们应该从依赖开始,从下往上迁移Typescript。对于项目中的一些低级库函数,即使是框架维护者提供的库函数,我们也不关心它们的实现逻辑,所以不需要重写成ts文件,只需要在里面加上声明文件即可我们的业务代码来调用。在我的项目中,service层的逻辑很简单。它只是传递参数来调用接口,没有添加任何其他逻辑。逻辑很简单,没必要改写成ts文件,所以我写了一个服务层文件的声明文件。为调用服务层的代码提供类型声明。声明文件写法一个js文件如下accountType可选*@param{String}data.username*@param{String}data.password*@param{String}data.genderX|女|M*@param{String}data.email*@param{Number}data.level*/createAccount(data){returnaxios.request({url:`/api/account/createUser`,方法:'post',数据:数据}).then((res)=>[res,null]).catch((err)=>[null,err]);},}可以看到在使用typescript之前,函数的参数、返回值等信息的提示都是通过jsdoc实现的,可以在调用Type和name的时候判断参数,但是jsdoc毕竟只是注释而已,并且不能提供类型验证,所以这里我们为其编写一个声明文件,编写的声明文件如下//service.d.tsinterfacecreateAccountParams{accountType?:string,username:string,password:string,gender:'X'|'F'|'M',email:string,level?:number}interfacecreateAccountReturn{userId:string,}exportinterfaceService{createAccount(data:createAccountParams):createAccountReturn}服务层接口文件声明文件完成。我们经常将service.js导出的实例绑定到main.js中的Vue原型上,这样我们就可以在vue组件中,通过vm.$service来方便的访问服务实例,但是Typescript不知道是什么属性在Vue实例上。这时候我们需要在之前添加的shims-vue.d.ts文件中添加几行代码。从“vue”导入Vue;从“pathToService/service.d.ts”导入服务;声明模块“*.vue”{导出默认Vue;}声明模块“vue/types/vue”{接口Vue{$service:服务}}得益于typescript提供的模块补充功能,我们可以在node_modules/vue/types/vue中补充我们需要在Vue上提供的属性。改写vue文件,我们需要改写原来要使用vue-property-decorator编写的vue文件。至此,一个Vue项目迁移到Typescript的过程就完成了,剩下的工作就是一步步将代码中的其他文件从js迁移到typescript。将方法绑定到Vue实例上除了我们之前提到的在Vue实例上挂载我们写的服务之外,大家一定知道在Vue项目中,我们经常会调用this.$refsthis.$routerthis.$store等.,typescript也会检查这些属性是否绑定到vue实例,那我们没有在类型系统中声明这些值,应该会报Property'$refs'doesnotexistontype[your_component_name]真相吧$refsvue-routervuex已经帮我们声明了对应的type,我们可以cd./node_modules/vue/types/目录查看,截取少量代码如下:exportinterfaceVue{readonly$el:Element;只读$options:ComponentOptions
