Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the shims-tsx.d.ts file do in a Vue-Typescript project?

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!

like image 323
Brandon Avatar asked Feb 11 '19 00:02

Brandon


People also ask

What is .TS file in Vue?

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.

How do I add TS to Vue?

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.

Does Vue use JS or TS?

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.


2 Answers

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.

like image 58
Timmmm Avatar answered Sep 19 '22 13:09

Timmmm


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.

like image 28
Ohgodwhy Avatar answered Sep 20 '22 13:09

Ohgodwhy