Vetur: The script lang=ts showing misleading errors in .vue files

Created on 12 Sep 2019  路  6Comments  路  Source: vuejs/vetur

  • [ x ] I have searched through existing issues
  • [ x ] I have read through docs
  • [ x ] I have read FAQ

Info

  • Platform: Win
  • Vetur version: 0.22.2
  • VS Code version: 1.38.1

Problem

image

Reproducible Case

Try vue js ts project from scratch using @vue/cli with option typescript and check whether vetur <script lang="ts"> is properly validating model properties, vuex getters and actions.

Also my tsconfig.json looks like this:

{
    "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "strict": true,
        "jsx": "preserve",
        "importHelpers": true,
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "sourceMap": true,
        "allowJs": false,
        "baseUrl": ".",
        "types": ["webpack-env", "jest"],
        "paths": {
            "@/*": ["src/*"]
        },
        "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
    },
    "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"],
    "exclude": ["node_modules"]
}

Most helpful comment

When using lang="ts", you should use export default Vue.extend({...}). Otherwise the error checking might not be accurate.

All 6 comments

I have bad news, unfortunately - the standard approach to Vuex components simply doesn't play well with lang="ts" components 馃槥

There's a good reason for it: when Vue provides helper functions to, for example, mapActions so that you can use this.success in your component, that's something that only Vue will understand at runtime in the browser. You're giving Vue a set of strings, and relying on Vue to correctly map those to make the correct methods available in your component.

But there's no way for TypeScript (& thus no way for Vetur) to know what those strings are supposed to mean at build time. This is a Vue + TypeScript issue, rather than a Vetur issue.

A few main options:

  1. Don't use lang="ts" in components that reference Vuex. This is what we do for our projects that didn't start as TS projects; in those cases, we only use TS components when they don't reference Vuex
  2. Use a wrapper for Vuex that is type-safe; this will add some boilerplate for each Vuex module, but works well, and gives full type safety (& no TS errors) when accessing Vuex. Recommendation: https://github.com/jackkoppa/typesafe-vuex
  3. Use the class syntax for TS components, and a Vuex helper package that uses decorators to help access Vuex modules: https://github.com/ktsn/vuex-class I wouldn't particularly recommend this, since Vue is generally moving away from class components

Certainly, the simplest answer is above is #1, with the obvious downsides in larger projects, that you'll have lots of untyped components. But, the nice thing about Vue is it gives us that choice, by allowing both JS & TS components in the same project

Hm.

  1. I cannot see a problem to interpretate script inside <script lang="ts"></script> as TypeScript. CLI can extract the script from the vue and put it into separate file (eg. *.vue.ts) before running.
  2. I am not sure about vuex actions but I assume properties user and userDemo should work with Vetur as it is a part of Vue so Vetur has a purpose to actually solve all those vue-specific syntax and validation. Otherwise I don't need Vetur just to validate TypeScript.
  3. I think all that validation Vue/TS is very important for Vue itself as to develop larger applications require strong type language like TypeScript. Nobody wont use Vue if it's loosing TS strenght and potency. They will rather choose Angular or React. Nobody will start enterprise app in Vue/JS or in Vue/TS without strong prebuild validation. I think Vetur is also should be responsible for this and help Vue with growth.

Regards

Oh, for sure, most of the TypeScript interpretation should work! And Vetur works just as well as the Vue CLI when compiling our lang="ts" components. When you run build with the CLI, for example, you'll find the same errors that you see in Vetur right now.

The good news is that you can solve a number of the problems that you see in your screenshot by using Vue.extend({}); it's required for TS components to get correct type inferences for Vue. Documented here: https://vuejs.org/v2/guide/typescript.html#Basic-Usage

And finally: you're completely right, that devs on the largest projects really need great TS support. It's certainly the case on our team. Vue is trying to address some of the things that make it very easy to get started with, but very hard to add accurate TypeScript support for (like mapping Vuex methods, and also mixins) with their composition RFC. It's going to be an additional way to instantiate components, and it will have perfect TypeScript support. Check it out! https://vue-composition-api-rfc.netlify.com/#basic-example

(I should mention - if you like the above composition approach, you can already start using it with the composition plugin. I wouldn't recommend that quite yet, since it's pretty early on, but it is an option - https://github.com/vuejs/composition-api/)

Thanks for your optimistic reply. I would definitely look at the composition api. I hope it will solve most of the vue/ts problems very soon. And hope it will be as intiitive and straight forward as vue framework itself.

When using lang="ts", you should use export default Vue.extend({...}). Otherwise the error checking might not be accurate.

Or just stop using bullshit like Vuex which encourages you to use magic strings to access a getter of a store. Go for MobX.

And even better: Stop using VueJS. It's just garbage.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thibautguedou3 picture thibautguedou3  路  3Comments

pdanpdan picture pdanpdan  路  3Comments

yoyoys picture yoyoys  路  3Comments

octref picture octref  路  3Comments

tczhangzhi picture tczhangzhi  路  3Comments