我我的很喜欢TypeScript也很喜欢Vue,但在二者共同使用的时候遇到一个问题。
Vue的实例化对象代理了全部实际ViewModel对象,具体可参见官方文档(
http://vuejs.org.cn/guide/instance.html#属性与方法)html
Vue的属性与方法:
每一个 Vue 实例都会代理其 data 对象里全部的属性vue
实际上vue实例不单单是代理了data属性,还代理了methods属性、computed属性等,能够经过 这篇文档 看到。那么怎么在TypeScript里面经过vue实例访问data属性和methods属性里面的变量是最大问题,不然就没办法使用TS的最大的做用——强类型检查。typescript
以下图能够看到:
app
虽然实际上vm.xxcanghaiFn是可用的,可是过不了TypeScript的编辑检查,提示不在'xxcanghaiFn'不在'Vue'类型中。
由于类型'Vue'中确定只有内部方法,天然会报错,虽然咱们能够经过<any>
语法强制使语法检查失效,以下代码:ide
var vm: any = new Vue({//vm变量增长any声明 el: "#app", data: { xxcanghaiData: "xxcanghai" }, methods: { xxcanghaiFn: function () { } } }); vm.xxcanghaiFn//无编译器报错
虽然没有编译器报错,但同时也没法再使用TS提供的智能补全,强类型检查等功能。这就跟直接写js没有任何区别了。函数
typeof
和declare
关键字将类型合并声明。<any>
声明并赋值。以下代码:ui
//核心声明,利用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内置函数及属性:
3d
也能实现识别咱们自定义的data属性和methods属性中的值:
代理
Vue有有一种特殊的ViewModel的属性——计算属性。
计算属性在使用ts的强类型的时候就会出错,代码以下:code
declare var VM: vuejs.Vue & typeof vmComputed; var vmComputed = { /** * 字符串计算属性 */ xxcanghaiCom: function () { return "xxcanghaiCom"; } } var vm: typeof VM = <any>new Vue({ el: "#app", computed: <any>vmComputed });
计算属会被ts的类型系统识别为一个函数,而出现函数相关的方法,此时调用字符串方法天然会报错。如图:

虽然计算属性实际上确实是一个函数,可是咱们但愿可以把计算属性拿来当一个字符串变量来使用。
这里可使用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
类型的规则为:
一、任何类型均可以被转换为
any
类型。
二、any
类型能够转换为任何类型。
因此先将计算属性的函数,或是getter,setter的Object声明为any
类型,再声明为你想实际使用的变量类型。以下:
declare var VM: vuejs.Vue & typeof vmComputed; var vmComputed = { /** * 字符串计算属性 */ xxcanghaiCom: <string>(<any>function () { return "xxcanghaiCom"; }), /** * getter和setter形式的字符串计算属性 */ xxcanghaiGetSet: <string>(<any>{ get: function () { return vm.xxcanghaiCom; }, set: function (newVal: string) { vm.xxcanghaiCom = newVal; } }) } var vm: typeof VM = <any>new Vue({ el: "#app", computed: <any>vmComputed });
效果以下图,虽然xxcanghaiGetSet
是object,但此处能够按照咱们想要的string
类型来使用。

本文比较初级,由于刚刚开始接触Vue,由于以前用过Angular和Avalon,因此上手起来还算舒服,以前用Angular的时候就由于用TypeScript写很是难受,遂打算好好研究下TypeScript与Vue的协同工做的问题。 写的比较匆忙,vue也尚未彻底了解,遂文中有不对的地方欢迎指正。:-)