关于Vue中的计算属性类型
TypeScript的强制类型声明语法
强制类型声明的局限性
计算属性类型的解决方案
后记
背景我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一些问题。
Vue的实例化对象代理了所有实际ViewModel对象,具体可参见(
)
Vue的属性与方法:
每个 Vue 实例都会代理其 data 对象里所有的属性
实际上vue实例不仅仅是代理了data属性,还代理了methods属性、computed属性等,可以通过 这篇文档 看到。那么怎么在TypeScript里面通过vue实例访问data属性和methods属性里面的变量是最大问题,否则就没办法使用TS的最大的作用——强类型检查。
如下图可以看到:
虽然实际上vm.xxcanghaiFn是可用的,但是过不了TypeScript的编辑检查,提示不在'xxcanghaiFn'不在'Vue'类型中。
因为类型'Vue'中肯定只有内部方法,自然会报错,虽然我们可以通过<any>语法强制使语法检查失效,如下代码:
虽然没有编译器报错,但同时也无法再使用TS提供的智能补全,强类型检查等功能。这就跟直接写js没有任何区别了。
解决方案将data属性,以及methods等需要合并进vue类型的对象分开写
利用TypeScript的typeof和declare关键字将类型合并声明。
最后new Vue时强制用<any>声明并赋值。
如下代码:
//核心声明,利用typeof将data和methods属性合并进Vue类型 declare var VM: typeof vmData & typeof vmMethods & vuejs.Vue; var vmData = { xxcanghaiData: "xxcanghai" }; var vmMethods = { xxcanghaiFn: () => { } } var vm: typeof VM = <any>new Vue({ el: "#app", data: vmData, methods: <any>vmMethods });效果如下,既可以实现识别Vue内置函数及属性:
也能实现识别我们自定义的data属性和methods属性中的值:
Vue中有一种特殊的ViewModel的属性——计算属性。
计算属性在使用ts的强类型的时候就会出错,代码如下:
计算属会被ts的类型系统识别为一个函数,而出现函数相关的方法,此时调用字符串方法自然会报错。如图:
虽然计算属性实际上确实是一个函数,但是我们希望能够把计算属性拿来当一个字符串变量来使用。
TypeScript的强制类型声明语法这里可以使用ts的强制类型声明语法 <TYPE>,来把指定类型强制声明为其他类型,如下:
var a; (<string>a).charAt(0);//合法 (<number>a).toFixed();//合法 强制类型声明的局限性但是此语法也有局限性,即只能强制声明那些未知类型的变量,不能强制声明已知类型的变量,如下:
var a = 0; (<string>a);//报错 Neither type 'number' nor type 'string' is assignable to the other.因为变量a已经可以被类型推断出为number类型了,遂不能再强制声明为string类型。
计算属性类型的解决方案解决方案为 利用any类型中转来实现强制类型声明转换。
在TypeScript中的any类型的规则为:
1、任何类型都可以被转换为any类型。
2、any 类型可以转换为任何类型。