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

原来TS中Declare的功能是这样的!

时间:2023-03-14 15:49:31 科技观察

当你在TypeScript项目中打开*.d.ts声明文件时,你可能会看到declare.你知道declare做什么吗?如果你不这样做,读完这篇文章后,也许你会的。在开发TypeScript项目的过程中,可能会以script标签的形式引入第三方的JS-SDK,比如引入微信公众平台的JS-SDK。初始化完成后,在TypeScript文件中调用JS-SDK提供的接口。例如调用拍照或从手机相册中选择图片的接口,实现选择图片的功能:wx.chooseImage({//Error:Thename"wx"cannotbefound.ts(2304)count:1,//默认9sizeType:["原始","压缩"],sourceType:["相册","相机"],成功:function(res){varlocalIds=res.localIds;},});虽然你按照微信开发文档使用了JS-SDK提供的接口,但是对于上面的代码,TypeScript编译器还是会提示相应的错误信息。为什么会这样?这是因为TypeScript编译器不识别wx全局变量。那么如何解决这个问题呢?答案是使用declare关键字来声明wx全局变量,这样TypeScript编译器就可以识别这个全局变量。声明varwx:any;上面代码中,declare是声明的意思,var的全称是variable,变量的意思。wx是全局变量的名称,any表示该变量的类型。看到这里,你会不会一头雾水?为什么在TypeScript项目中可以正常使用JSON、Math或Object等全局变量?这是因为TypeScript内部帮我们完成了声明操作。前面提到的那些全局变量在lib.es5.d.ts声明文件中声明://typescript/lib/lib.es5.d.tsdeclarevarJSON:JSON;declarevarMath:Math;declarevarObject:ObjectConstructor;其实,declare除了声明全局变量,关键字还可以用来声明全局函数、全局类或者全局枚举类型等,你在工作中可能用到的eval、isNaN、encodeURI、parseInt等函数也是在lib.es5.d.ts声明文件中声明:declarefunctioneval(x:string):any;declarefunctionisNaN(number:number):boolean;declarefunctionencodeURI(uri:string):string;declarefunctionparseInt(字符串:字符串,基数?:数字):数字;需要注意的是,在声明一个全局函数的时候,我们不会包含函数的Implementation。有了声明文件,TypeScript编译器就可以识别上述全局的JavaScript函数。之前没有找到名字为“wx”的问题的解决方法,比较暴力。更好的方案是创建一个wx.d.ts文件,详细声明JS-SDK中提供的方法。幸运的是,在使用普通JavaScript开发的第三方库时,不需要自己定义类型声明文件。使用TypeScript官网提供的类型声明文件搜索功能,或许可以找到优质第三方库对应的TypeScript类型声明文件。一旦找到,就可以通过npm安装包含所需类型声明文件的模块。接下来介绍declare的其他用法。打开Vite项目中的client.d.ts声明文件,会看到很多声明模块的代码。//packages/vite/client.d.tsdeclaremodule'*.css'{constcss:stringexportdefaultcss}declaremodule'*.jpg'{constsrc:stringexportdefaultsrc}declaremodule'*.ttf'{constsrc:stringexportdefaultsrc}在上面的代码中,我们声明了css、jpg和ttf模块。为什么需要声明这些模块?因为如果不声明它们,TypeScript编译器将无法识别上述模块,并提示相应的错误信息。从“./file.css”导入css;//错误:找不到模块“./file.css”或其对应的类型声明。ts(2307)从“./abao.jpg”导入标志;//错误:找不到模块“./abao.jpg”或其对应的类型声明。ts(2307)在声明模块时,为了避免为每个资源都声明其对应的模块,TypeScript2.0开始支持通配符(*)形式来声明模块的名称。此外,TypeScript还允许您通过declaremodule语法扩展现有模块中定义的类型。例如,如果你想为每个Vue组件实例添加$axios属性,你可以这样做:;}}之后,通过配置对象的globalProperties属性,你可以高效地为每个组件实例添加$axios属性:import{createApp}from"vue";importaxiosfrom"axios";importAppfrom"./App.vue";constapp=createApp(App);app.config.globalProperties.$axios=axios;app.mount("#app");最后,在组件中,可以通过组件内部实例的proxy.$axios属性访问axios对象:import{getCurrentInstance,ComponentInternalInstance}from"vue"const{proxy}=getCurrentInstance()asComponentInternalInstanceproxy!.$axios。get("https://jsonplaceholder.typicode.com/todos/1").then((response)=>response.data).then((json)=>console.log(json));