I have a Vue project that I'm building to learn both Vue and TypeScript. The project has a chunk of static data that I've chosen to make available to components as a Vue plugin, adding a property to the Vue prototype.
import _Vue from 'vue';
export default function myPlugin(Vue: typeof _Vue): void {
Vue.prototype.$myPlugin = { one: 1, two: 2 };
}
I followed the advice in a post by Peter Kuhn, defining the property type in a test-plugin.d.ts
file.
import Vue from 'vue';
declare module 'vue/types/vue' {
interface Vue {
$myPlugin: object;
}
}
Finally, I import
and use()
the plugin.
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');
However, when I reference the property in a single-file Vue component, both vscode and the TypeScript transpiler throw an error that the property doesn't exist.
<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>
The error:
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>
Despite the error, this.one === 1
as I'd expect once the code is built and executed. Can anyone pinpoint what I'm doing wrong, here?
I've posted the sample code to 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"
}
Now, you should be able to get your Vue app up and running in TypeScript with features like defineComponent , data, props, computed properties, methods, and watchers. Vue 3.0 includes better support for TypeScript out of the box, and the entire Vue code was rewritten in TypeScript to improve maintainability.
Actually, you can also implement TypeScript one file at the time with Vue (if you add it to an existing project). You take one of your Vue files and add the lang="ts" inside the script tag. Then you modify your component to use the Class API and fix the potential errors TypeScript found. It's really easy!
When you augment Vue typings for use with a plugin - as in test-plugin.d.ts
- you need to import Vue first:
import Vue from 'vue'
declare module 'vue/types/vue' {
interface Vue {
$myPlugin: object
}
}
Its explained here in the docs.
update
I don't see mention of it your post, but if you haven't done so you also need a shim for single file components:
// sfc.d.ts
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
You can see this in the TypeScript-Vue-Starter repository.
update
Disregard the above, I didn't notice the sample repo. I managed to resolve the type error, see the changes here.
answer
As noted by @kccricket, the plugin's implementation and declaration files were named the same, thus causing the module in resolve incorrectly.
// original file names
test-plugin.ts
test-plugin.d.ts
what worked for me was to have the below declaration inside the .ts plugin file:
declare module 'vue/types/vue' {
interface Vue {
$myPlugin: object;
}
}
i tried having the same thing in the .d.ts file as recommended in that article, but intellisense still couldn't see it properly in the component code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With