网站搜索

vue.js - 如何在 vue 中使用 TypeScript 并且不使用模块


在 package.json 中我有

"devDependencies": {    
   "vue": "2.5.16"
}

这会在 node_modules\vue\types 中给我生成 index.d.ts, vue.d.ts 等文件。起初我遇到的问题是当我写 new Vue({...}); 之类的代码时,找不到 vue ((TS) Cannot find name 'Vue')。在阅读了这个讨论帖之后,我通过添加一个 custom.d.ts 文件解决了这个问题:

import _vue = require('vue');

declare global {
    const Vue: typeof _vue;
}

并使用 /// <reference path="../Declarations/custom.d.ts" /> 引用它

显然原因是 Vue 的声明是以外部模块格式(使用 export)的,如果不使用模块系统,则需要全局模块。

但是现在 IntelliSense 给我显示:"(TS) 无法对类型缺少调用或构造签名的表达式使用 'new'。",并且构建失败。

我正在使用 TypeScript 2.8,并且使用 outFile,没有模块(只有 reference XML 注释)。

编辑:我以为我通过使用找到了答案

const Vue: typeof _vue.default;

这使得 new Vue() 语句的错误消失。但当我尝试声明一个类型为 Vue 的变量时,我又会得到 Cannot find name 'Vue' 错误:

var app = new Vue({}); // Works
var app2:Vue = new Vue({}); // Doesn't work

答案#1

我通过在 custom.d.ts 中添加以下内容弄好了基本运行:

import * as _vueIndex from "vue";
import * as _vue from "vue/types/vue";

declare global {
    const Vue: _vueIndex.VueConstructor; // related to vue.d.ts "export const Vue: VueConstructor;"

    namespace Vue {
        //type Vue = typeof _vueIndex.default; // For some reason this becomes VueConstructor interface instead of Vue interface
        type Vue = _vue.Vue;
        type CreateElement = _vueIndex.CreateElement;
        type CombinedVueInstance<Instance extends Vue, Data, Methods, Computed, Props> = _vue.CombinedVueInstance<Instance, Data, Methods, Computed, Props>;
        /*Other interfaces*/
    }
}

现在可以做类似这样的事情:

var app: Vue.CombinedVueInstance<Vue.Vue, any, VmMethods, any, any> = new Vue({
    el: '#app',
    methods: new VmMethods()
});

console.log(app.toggleSidebar()); // toggleSidebar is a public function in VmMethods
console.log(app.nonExisting()); // ReSharper gives correct cannot resolve error but TypeScript still transpiles for some reason, which gives a run time error

ReSharper 仍然显示 无法正确解析符号 Vue,可能它位于不可访问的模块中,但 TypeScript 可以正确转译并运行。