vite: Typescript checking in Vue SFCs does not work as expected

In the docs (README) under the Typescript section, it says:

[Vite] does NOT perform type checking. It assumes type checking is taken care of by your IDE and build process (you can run tsc --noEmit in the build script).

However, running tsc --noEmit is problematic.

Firstly, if you turn on isolatedModules in your tsconfig, then tsc will fail, because Vue exports const enums (there’s a bug reported in the Vue repo about that). You can just turn this flag off, but then you have to be careful not to use stuff that wouldn’t work outside a module.

Secondly, even if you include .vue files in your tsconfig, they do not get type checked. Since the majority of your code is in SFCs (if you use them) in a Vue app, this makes it pointless.

In a webpack build with Vue CLI setup, the script portion of SFCs is transpiled with babel (similar to using esbuild here) and checked with typescript, using ts-loader or similar. In Vite, this isn’t happening, so the docs are misleading.

Since Vue 3 is built in Typescript, more people are likely to use TS going forwards, people moving from Angular to Vue are likely to start with TS, so there really needs to be solid support for it. I appreciate that the build process doesn’t need it, but type checking is still important. Whilst the IDE can warn you, in any professional set up, it needs to be part of the CI process, so a way to configure tsc to do this is necessary.

Is there a way to get type checking of SFCs? Minimum the script part, but ideally the code within templates too.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 34
  • Comments: 18 (6 by maintainers)

Most upvoted comments

@robyedlin I see how this conversation is slightly related to the one you link, but that is talking about wider features such as unit testing being configured out of the box. I appreciate those things might be non goals as commented by Evan, because this is just supposed to be a build tool. However, type checking is very much a (necessary) part of the build process, so it is relevant. I’d be interested to know if @yyx990803 thinks this is also a non goal and why.

Another commenter on that thread suggested that they preferred using the IDE for type checking and not duplicating the functionality. That’s all very well for single developers or very small teams, but completely unacceptable at scale. Also many of the IDE plugins are buggy and miss things.

@underfin is this yet another - I don’t need this, because I don’t use it, therefore I’ll just close it? If it needs doing (I think it really does) then it still remains a missing feature at least, so should be left open. IMHO it’s actually a bug, as the primary use case of this library is for building Vue 3, which is written in Typescript and so should support its proper use. Since the docs mention Typescript support and that if you want to do type checking, you just run tsc --noEmit then this should actually work, have docs to show how it can work, or be made very clear that it will never work.

I totally get that we want to be able to do transpiling as quickly as possible, but without actually doing type checking at some point, there really is no purpose to using Typescript.

I’d like to second that maybe this would be more appropriately labelled as a bug instead, since Vite lists TypeScript as one of its biggest features in the readme

@yyx990803 How do you mean this “Closing - the vue-ts template now checks SFCs during build.”.

If I create a typescript error, neither “dev” or “build” catches it ?

For instance in a clean vite vue-ts setup - if I misspell for instance defineComponent. I get a runtime error, but no buildtime error:

` import { defineComponent } from ‘vue’ import HelloWorld from ‘./components/HelloWorld.vue’

export default efineComponent({ name: ‘App’, components: { HelloWorld } }) `

@underfin Is the theory that type checking should only show warnings in the IDE and not be part of the save/build/CI process? Seems like this opens up the possibility for errors during CI, as it’s easy to miss warnings in the IDE.

Bigger but related question. Is Vite supposed to be for rapid prototyping or for production apps?

See https://github.com/znck/vue-developer-experience which provides command line type checking with support for *.vue files. It’s still in pre-alpha but @znck is making some good progress.

@antfu here’s a gist https://gist.github.com/spikyjt/5431daf5710f98b3c7eb77975c893563 just in plain JS for now, but I’ll convert to TS for the lib and publish when I get back.

Thanks for re-opening @underfin - sorry if I appeared to be having a rant!

Just to make it clear that I’m happy to contribute, I’ve written a script to use the sfc compiler and output the Typescript part if available, to prepare it for checking with tsc.

I’m going on holiday today, but when I get back, I’ll share it as a lib after some clean up and look at writing a plugin for Vite and adding docs PRs, if acceptable.

I would welcome feedback on my strategy:

  1. I tried using the Typescript programmatic API, using @typescript/vfs so that everything could be checked in memory. Unfortunately I found importing the required libs too cumbersome, so abandoned that. This would be the preferred method though, I think. (Or maybe a Typescript plugin?)
  2. Instead, I decided to parse the SFCs with @vue/compiler-sfc and extract the script section to a file with the .ts extension after the same name as the .vue file, written alongside it.
  3. This strategy allows simply running tsc --noEmit and everything works as it should, because imports to SomeName.vue will be resolved to SomeName.vue.ts.
  4. There is a clean up script to delete the files afterwards, so you can chain it with a call to parse, then tsc, then clean.
  5. I’d have preferred these files to be written out of the way of the actual src, but I think I’d get into library hell again.

Any advice on how to implement this better would be useful, but perhaps the compiler-sfc or vue-loader devs would be best placed to help?

Is there a way to get type checking of SFCs? Minimum the script part, but ideally the code within templates too.

If you want this, you can write a plugin for this(extract script block and type check it).It’s not include core for now.For the template code type check is also experimental inside vetur .

@chessydk you get the error at runtime because your bundle is also built at runtime, that’s how ES-bundlers work. Your CLI cannot display anything because it hasn’t processed any of your files.

@chessydk comments in old issues are probably going to be ignored. Please start a new GitHub Discussion about this or join the chat at Vite Land.

vue-ts template now checks SFCs during build

I do not see anything that does that. Template https://github.com/vitejs/vite/tree/main/packages/create-app/template-vue-ts doesn’t have any specific packages.

Vite doesn’t perform type checking on build not only in SFC, but also in regular typescript files.

I don’t complain, just " If it needs doing (I think it really does) then it still remains a missing feature at least, so should be left open". For linting I found the solution — vite-plugin-eslint, for type checking still cannot find working solution.

Edit: vue-tsc solved this 🎉.


Maybe I misunderstanding something here, but vite build didn’t do type check for Vue SFCs in my repo. Is it expected?

Repo: https://github.com/yangmingshan/vite-issue

Expect: https://github.com/yangmingshan/vite-issue/blob/main/src/components/HelloWorld.vue#L43 will report type error when run vite build.

Actual: build success without error.

Closing - the vue-ts template now checks SFCs during build.