When creating a Vue project with typescript, two declaration files are included: shims-vue.d.ts and shims.tsx.d.ts.
//shims-vue.d.ts declare module "*.vue" { import Vue from 'vue'; export default Vue; }
And:
//shims-tsx.d.ts import Vue, { VNode } from 'vue'; declare global { namespace JSX { // tslint:disable no-empty-interface interface Element extends VNode {} // tslint:disable no-empty-interface interface ElementClass extends Vue {} interface IntrinsicElements { [elem: string]: any; } } }
While creating a small project (without the Vue CLI) I forgot to include the second (shims.tsx.d.ts) and my project compiles and runs as expected (without error).
I found this post about it: https://github.com/vuejs/vue-cli/issues/1198, but was hoping for more clarification.
I am just curious what this file does and why it is included? In other words, what I would have to do to "break" my app if I don't include this declaration file.
Thanks!
TypeScript is a JavaScript superset created by Microsoft which turns the loosely-typed language into a strictly-typed language. It can be summarized as ECMAScript 6 with optional type declarations. Evan You, the creator of Vue. js, has stated that Vue. js 3.0's codebase will be rewritten entirely in TypeScript.
To let Typescript enters into your Vue components, 2 additions are mandatory in each component file: Adding the lang="ts" attribute to the script tag so that Typescript can recognized it.
Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.
This link was the only decent explanation I could find. Basically it is to do with Webpack.
If you aren't using Webpack - you're only using Typescript, then doing something like this is an error:
import Foo from "./Foo.vue";
Because obviously Typescript doesn't understand .vue
files - they aren't actually Typescript modules.
However, if you set up a Vue project you'll find that it does it all the time. How does that work? Webpack! As far as I can tell (I have tried to avoid insanity by learning anything at all about webpack), this is basically Webpack's job - it goes through all of the import
files in your Javascript/Typescript, and "bundles" them, i.e. it merges them into one file.
But it extensible with "loaders" (terrible name) that can be added to handle particular file formats. For example you can configure it to use a CSS loader. That means when it finds
import "./foo.css"
It will bundle the CSS into the output, and probably add some Javascript to insert it into the DOM at runtime, or some nonsense like that.
Anyway, there's also (I presume) a loader for *.vue
files that handles bundling those. So that's why import Foo from "./Foo.vue"
works. Why do we need the shim file?
Because Typescript still isn't happy. It doesn't know anything about Webpack, so it will still throw an error when you try and import Foo.vue
(it'll tell you Can't find module "./Foo.vue"
).
The solution is shims-vue.d.ts
. The filename does not seem to be important, as long as it ends with .d.ts
. I guess Typescript looks for all .d.ts
in the same directory or something like that.
In any case, the contents are this:
declare module "*.vue" { import Vue from 'vue'; export default Vue; }
Which basically means, "every time you import a module with the name *.vue
(wildcards are supported), then don't actually do it - instead treat it as if it had these contents".
This is how it seems to behave for me: If you do import Foo from "./Foo.vue"
then the type of Foo
will by Vue
. There does not seem to be a way to actually import the Foo
type.
Edit: Actually I think it works *if you import the component in another .vue
file. If you import it from .ts
then you just get an alias for Vue
. This is annoying in tests! I made another question about this.
The first file helps your IDE to understand what a file ending in .vue
is
The second file allows you to use .tsx
files while enabling jsx
syntaxsupport in your IDE to write JSX-style typescript 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