本文将采用与本系列之前两篇相同的做法,从单元测试入手,结合 ts 类型定义,尝试弄懂 defineComponent() 的明确用法。 ?顺藤摸瓜:用单元测试读懂 vue3 watch 函数 ?...基础类型接口 此类型没太多好说的,就是我们熟悉的 Vue 2.x 组件 options 的定义: // vue 2.x 项目中的 types/options.d.ts export interface...composition 式组件 options 类型基础接口 继承自符合当前泛型约束的 Vue2ComponentOptions,并重写了自己的几个可选属性: interface ComponentOptionsBase...(): T } | { new (...args: string[]): Function } 属性验证类型定义 export interface PropOptions { ...: any }>, RawBindings, D, C, M> 将 props 匹配为属性名组成的字符串数组: // src/component/componentOptions.ts export
意味着当我们仅是安装 Vue 的声明文件时,一切也都将会按预期进行: this,就是 Vue; this 属性上,具有 Methods 选项上定义的同名函数属性; 在实例 data、computed、prop...上定义的属性/方法,也都将会出现在 this 属性上; .........Methods 当我们创建 Vue 实例,并在 Methods 上定义方法时, this 不仅具有 Vue 实例上属性,同时也具有与 Methods 选项上同名的函数属性: new Vue({ methods...$el // Vue 实例上的属性 } }, created () { this.test() // methods 选项上同名的方法 this....Vue) => any 的集合 type Methods = Record any> 这会存在一个问题,Methods 上定义的方法里的 this,全部都是
其规避或解决了 JavaScript 一些常见大量重复出现的错误源,比如 Uncaught TypeError,加入了如:强类型判断与其他有趣的特性...据说能稍微方便别人看懂你的代码(对于我来说不存在的...需要注意的是在使用 @nuxtjs/axios 模块时(参照以下文章以了解使用原因) 可以通过 @types 声明它的类型(第三方模块类型声明在后文提及) 博客 Nuxt.js 移植重构与服务端渲染入门实现...文件声明类型,可以于根目录新建 types 文件夹,其中包含 d.ts 文件来配置全局类型声明。...新建 types/vue-shim.d.ts 文件配置如下: declare module "*.vue" { import Vue from 'vue' export default...Vue } ↑ vue-shim.d.ts 同时项目中还引用了其他来自第三方的依赖,也需要为它们声明类型,可以新建 types/global.d.ts 文件样例配置如下: declare module
意味着当我们仅是安装 Vue 的声明文件时,一切也都将会按预期进行: this,就是 Vue; this 属性上,具有 Methods 选项上定义的同名函数属性; 在实例 data、computed、prop...上定义的属性/方法,也都将会出现在 this 属性上; .........Methods 当我们创建 Vue 实例,并在 Methods 上定义方法时, this 不仅具有 Vue 实例上属性,同时也具有与 Methods 选项上同名的函数属性: new Vue({ methods...$el // Vue 实例上的属性 } }, created () { this.test() // methods 选项上同名的方法 this....this: Vue) => any 的集合 type Methods = Record any> 复制代码 这会存在一个问题,Methods 上定义的方法里的
JavaScript开发中经常遇到的错误就是变量或属性不存在,然而这些都是低级错误,而静态类型检查恰好可以弥补这个缺点。什么是静态类型?...为vue实例添加属性/方法 当我们在使用this.route或一些原型上的方法时,typescript无法进行推断,在编译时会报属性route不存在的错误,需要为这些全局的属性或方法添加全局声明 对shims-vue.d.ts...: any; } 自定义三方库声明 当使用的三方库未带有 *.d.ts 声明文件时,在项目编译时会报这样的错误: Could not find a declaration file for module...安装 @types/vuedraggable 按照提示先选择第一种方式,安装 @types/vuedraggable,然后发现错误 404 not found,说明这个包不存在。...建议及注意事项 改造过程 在接入 TypeScript 时,不必一次性将所有文件都改为ts语法,原有的语法也是可以正常运行的,最好就是单个修改 初次改造时出现一大串的错误是正常的,基本上都是类型错误,按照错误提示去翻译进行修改对应错误
看来,这将会是一个 any 类型: ?...这意味着我们可以使用 someProp 上的任意属性(存在或者是不存在的)都可以通过编译。为了防止此种情况的发生,我们将会给 Prop 添加类型注释。...: any): Object; (): any; (value: any): any; // 其它属性 .... } 复制代码 类似的,当我们使用关键字 as 断言 Object 为 ()...而类做为 TypeScript 特殊的存在(它既可以作为类型,也可以作为值),当我们使用 vue-class-component 并通过 $refs 绑定为子类组件时,便能获取子组件上暴露的类型信息:...在这个 PR 下,我找到相关解答:这个 PR 里,Vetur 提供解析其他 .vue 文件的功能,以便能获取正确的信息,当 .vue 文件不存在时,会读取 .d.ts 里的信息。
TypeScript 的静态类型检查是个好东西,可以避免很多不必要的错误, 不用在调试或者项目上线的时候才发现问题 。...可以随便变更类型 (当这个值可能来自于动态的内容,比如来自用户输入或第三方代码库) let notSure: any = 4; notSure = "我可以随便变更类型" // 不报错 notSure...vue-property-decorator 是在 vue-class-component 上增强了更多的结合 Vue 特性的装饰器,新增了这 7 个装饰器: @Emit @Inject @Model...+ typescript + iview + Nuxt.js 的服务端渲染还有不少坑, 而 vue + typescript + element + Nuxt.js 对 ssr 的支持已经不错了,所以选择了...一开始用 Vue + TS 来搭建时,我也是挺抵触的,因为踩了好多坑,而且很多类型检查方面也挺烦人。后面解决了,明白原理之后,是越用越爽,哈哈。 ?
泛型与 Any Ts 的特殊类型 Any 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然: // 方法一:带有any参数的方法 function any_func(arg: any):...因为 any可以代替任意类型,所以该方法在传入参数不是数组或者带有 length属性对象时,会抛出异常。...'123'); // 错误类型的实际参数 3.3 自定义类型: Interface vs Typealias Interface,国内翻译成接口。...有些是只在某些条件下存在,或者根本不存在。 例如给函数传入的参数对象中只有部分属性赋值了。带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 ?符号。...在现有写法的基础上,几乎 0 成本的迁移。 但是 Vue.extend模式,需要与 mixins 结合使用。
age: number; /* 可选属性:定义该属性可以不存在 */ hobby?...: string; /* 任意属性:约束所有对象属性都必须是该属性的子类型 */ [key: string]: any; } /* 报错:无法分配到 "jobId",因为它是只读属性...IA│IB"上不存在属性"a"”。...类型 “IB” 上不存在属性 “a" */ /* 结论:访问联合类型时,处于程序安全,仅能访问联合类型中的交集部分 */ if (arg.a) { console.log...R: any // 关键字【extends】跟随泛型出现时,表示类型推断,其表达可类比三元表达式 // 如: T == 判断类型?
; } } 当然,如果你代码比较多,改造太耗时间,那就用'any大法'吧,每一个属性直接用 any 就完事了。...对象属性赋值报错 动态对象是 js 的特色,我先定义个对象,不管啥时候我都可以直接往里面加属性,这种报错,最快的改造办法就是给对象申明 any 类型。...函数中使用this 根据写法不同,大概会有以下4种报错: 1.类型“NodeModule”上不存在属性“name”。...ts(2339)2.类型“typeof globalThis”上不存在属性“name”。ts(2339)3."this" 隐式具有类型 "any",因为它没有类型注释。...VSCode调试ts 步骤七、类型加强、消除any 接下来要做的就是补充 Interface、Type,逐步将代码中的被业界喷得体无完肤的 any 干掉,但不要妄想去掉所有 any ,js 语言说到底还是动态语言
整体流程 编译和还原本质上都是把代码解析成语法树然后进行变换,再生成新的代码。 vue 模板在编译时基本没有丢掉原始信息,因为我们可以做到比较精准的还原。...完整的 js 语法树节点类型定义可以在 ts-estree.ts[2] 查阅。 简单的 api 调用就可以获取到渲染函数的语法树。...,我们还需要 vue 模板的语法树节点类型定义,才能正确地完成转换。...一个 vue 模板语法树节点类型定义如下: 删减了非必要属性,完整版本可以查看 index.d.ts[3] type ASTNode = ASTElement | ASTText | ASTExpression...// vue/types/vue.d.ts export interface CreateElement { (tag?
,配置ts属性,再在eslint增加 ts代码规范。...": false, // strict默认为true——必须要确保每个实例的属性都会初始值 "noImplicitAny": false, // false表示运行隐式的any类型,也就是允许不设置任何类型... IntrinsicElements { [elem: string]: any; } } } 项目改造到这里就基本结束了 TS一些注意事项 这部分对于刚刚改造,需要提醒成员的事项 TS类型 any...可选属性vs null undefined null 和 undefined 是 ts 中的基础类型,分别具有值 null 和 undefined,默认情况下它们是所有类型的子类型,即可以赋值给任意类型...null的发明者,Tony Hoare,称它为价值亿万美金的错误。
,接收泛型T默认为any,代表的是实际接收到的返回数据类型,一般会将T设置为IDataType。...),而data的类型即为IDataType 封装统一使用原生实例的request方法来进行 //T默认是any类型,返回值默认是AxiosResponse request<T = any,...// 对响应错误做点什么 return Promise.reject(error); }); 复制代码 全局拦截在JJRequest的构造函数中实现 //service/request/request.ts...将出现响应失败404) 三、封装三(自定义实例级别的拦截器,添加token) 需实现的效果如下: //service/index.ts const jjRequest = new JJRequest(...: (error: any) => any } 复制代码 自定义请求配置接口,可选属性,可配可不配 interface IJJRequestConfig extends
4、使用TS改写当前代码遇到各种错误问题? 对象属性不存在错误:: 这种情况一般在于,该对象值TS知道其有明确类型(不是any,如果是any就不会报错了),但是当前要访问的属性不存在与其已知类型结构。...这种情况分两种办法解决: - 如果能修改该值的类型声明,那么添加上缺损值的属性即可; - 否则,使用 // @ts-ignore 注释,或者使用类型断言,强制为 any 类型:(this.props as...any).notExists 类型不明确的错误: 即一个值的类型可能被注解为联合类型,那么在直接访问时,TS无法确定当前值到底属于哪个精确的类型,所以会报告错误。...这种情况有以下解决拌饭: - 使用类型保护(type guards) - 使用类型断言 - 使用 // @ts-ignore 注释 应该优先考虑类型保护,因为类型保护本质上就是增加代码逻辑,帮助TS...值可能不存在的或为undefined的错误: 这种情况其实是上面提到的类型不明确错误的一种,一般发生在可选属性或者可选参数时。
T[K] 可以使用 T[K] 作为返回类型。 key 的默认值 尝试了各种方式,虽然可以运行,但是TS会报错。可能是我打开的方式不对吧。...当然,也有一点麻烦的地方,需要多传入一个属性,记录组件要操作的字段名称。 组件的 props 的类型是 shallowReadonly,即根级只读,所以我们可以修改传入的对象的属性。...ref-model-range.ts import { customRef } from 'vue' interface IModel { [key: string]: any } /** *...TS 的尴尬 可能你会注意到,上面的例子没有使用 colName 属性,而是直接传递字符层的参数。 因为 TS 只能做静态检查,不能做动态检查,直接写字符串是静态的方式,TS可以检查。...但是使用 colName 属性的话,是动态的方式,TS的检查不支持动态,然后直接给出错误提示。 虽然可以正常运行,但是看着红线,还是很烦的,所以最后封装了个寂寞。
领取专属 10元无门槛券
手把手带您无忧上云