typescript - 为什么 TypeScript 不识别 Vue 插件的模块扩充?

标签 typescript vuejs2

我有一个 Vue 项目,我正在构建它来学习 Vue 和 TypeScript。该项目有一大块静态数据,我选择将其作为 Vue 插件提供给组件,向 Vue 原型(prototype)添加一个属性。

import _Vue from 'vue';

export default function myPlugin(Vue: typeof _Vue): void {
  Vue.prototype.$myPlugin = { one: 1, two: 2 };
}

我遵循了 post by Peter Kuhn 中的建议, 在 test-plugin.d.ts 文件中定义属性类型。

import Vue from 'vue';

declare module 'vue/types/vue' {
    interface Vue {
        $myPlugin: object;
    }
}

最后,我importuse() 插件。

import Vue from 'vue';
import App from './App.vue';
import MyPlugin from './test-plugin';

Vue.use(MyPlugin);

new Vue({
  render: (h) => h(App),
}).$mount('#app');

但是,当我在单文件 Vue 组件中引用该属性时,vscode 和 TypeScript 转译器都会抛出该属性不存在的错误。

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
  data: {
    one: 0,
  },
  created(): void {
    this.one = this.$myPlugin.one;
  },
});
</script>

错误:

ERROR in /Users/kccricket/Projects/what-the-heck/vue-plugin-test/src/components/HelloWorld.vue
43:21 Property '$myPlugin' does not exist on type 'CombinedVueInstance<Vue, { one: number; }, {}, {}, Readonly<{ msg: string; }>>'.
    41 |   },
    42 |   created(): void {
  > 43 |     this.one = this.$myPlugin.one;
       |                     ^
    44 |   },
    45 | });
    46 | </script>

尽管有错误,this.one === 1 正如我在构建和执行代码后所期望的那样。任何人都可以在这里查明我做错了什么吗?

我已将示例代码发布到 GitHub:https://github.com/kccricket/what-the-heck/tree/master/vue-plugin-test

环境

"dependencies": {
  "vue": "^2.5.16"
},
"devDependencies": {
  "@vue/cli-plugin-typescript": "^3.0.0-rc.5",
  "@vue/cli-service": "^3.0.0-rc.5",
  "vue-template-compiler": "^2.5.16"
}

最佳答案

当您增加 Vue 类型以与插件一起使用时 - 如 test-plugin.d.ts - 您需要先导入 Vue:

import Vue from 'vue'

declare module 'vue/types/vue' {
  interface Vue {
   $myPlugin: object 
  } 
}

其解释 here in the docs .

更新

我没有看到你的帖子提到它,但如果你还没有这样做,你还需要一个用于单个文件组件的垫片:

// sfc.d.ts
declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}

你可以在 TypeScript-Vue-Starter 中看到这个存储库。

更新

请忽略以上内容,我没有注意到示例存储库。我设法解决了类型错误,请参阅更改 here .

回答

正如 @kccricket 所指出的,插件的实现文件和声明文件的名称相同,因此导致模块解析不正确。

// original file names

test-plugin.ts
test-plugin.d.ts

关于typescript - 为什么 TypeScript 不识别 Vue 插件的模块扩充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51469620/

相关文章:

javascript - 如何从另一个组件调用函数 [Angular]

javascript - 类型数组 :- Cannot invoke an expression whose type lacks a call signature 的 typescript 错误

vuejs2 - v-for 内部的 v-if 和 v-else 用于不同的文本渲染

javascript - Vue.js vuex 状态无法正常工作

vue.js - 如何在 VueJS 2 中使用相同的用户表单组件来创建和编辑用户?

javascript - VueJS 基于输入过滤数组

reactjs - 如何将 setter 钩子(Hook)传递给子组件并满足 TypeScript

typescript - call() 没有返回正确的类型

typescript 扩展基类对象属性

django - Vue 和 Django 开发环境