rfcs
rfcs copied to clipboard
Question on the general TypeScript support in Vue 3
Hi. I have a few questions regarding TypeScript support that will come along with Vue 3.0. I wanted to ask them originally in https://github.com/vuejs/rfcs/pull/42 but I thought my comment would quickly disappear in that thread and maybe other people will have a similar questions so I hope you don't mind me opening a new issue here.
In the section Type Inference you briefly described how type inference will work in the script
tag, but all the examples presented there touches only functions composition, type checking props. What I'd like to know is if/how TS will generally work in other parts of Single File Components.
Questions I have at the moment:
- Will type inference work in the templates of our
.vue
components? I guess during development Vetur for VS Code will help us with that, but how will it work during compile time? - Will it be possible to have things like refs, slots strongly typed?
Thank you for reply. I really appreciate it :)
I think type inference in template interpolation is related to vuejs/vetur
@sqal I share the concern with you. :) Previously I tend to choose render functions rather than templates, in order to get full type inference support. However, in vue 3.0 templates will get more performance optimization and generally will be faster then hand-written render functions. That puts typing support in templates vital for me.
I just confirmed with @octref (author of Vetur) a few days ago - Vetur will be able to leverage the type information of the <script>
section to provide autocompletion and type inference in <template>
.
There is already working feature in Vetur for template type checking https://vuejs.github.io/vetur/interpolation.html. And we are planning to make it work on compile time.
As for template type checking, it is still behind an experimental flag. It would be appreciated if you feedback about it. 🙂
how will it work during compile time?
Vetur will have a CLI version where you can get diagnostics. Normally you would be using one of the editor integration based on VLS so you don't have to run this separately, but you do have the option.
I don't think putting type-checking into the webpack compilation chain (if that's what you mean by "compile time") is an good idea:
- It doesn't have a good place to surface diagnostics. I hate browser overlays for displaying errors. Editor is the most natural place to surface errors.
- There's a lot of integrations I have to do directly on TypeScript API for this to work. Doing that all under webpack or a webpack loader is impractical.
But you can put the Vetur CLI as part of your CI.
refs, slots strongly typed?
You need to be more specific.
@octref, for example, let's image the following component:
// some-component.vue
<template>
<section class="some-component">
<some-input ref="someInput"/>
</section>
</template>
<script>
import SomeInput from 'components/some-input.vue';
export default {
components: { SomeInput }
setup(props, context) {
context.refs.someInput; // Can `someInput` here have the type of SomeInput imported above?
}
}
</script>
The thing is that it most likely requires type inference not from pre-set types, but direct type extension of the component from the Vetur's side.
I would prefer to see this being integrated into a loader for webpack aswell. Maybe it would be great to integrate it into fork-ts-checker-webpack-plugin as it already does type checking and linting of the script part of SFC's. I know there is the idea to have a CLI version available but I still think it would be better for a few reasons.
-
Transparency: It will be confusing what loader, plugin or additional step is doing what kind of tests/checks. E.g. I have ts-loader, fork-ts-checker-webpack-plugin and vue-loader running...together with the new additional step it's getting hard to figure out what part of the steps is now taking care of transpilation, what part is taking care of type checking and what part is taking care of linting.
-
Speed: If fork-ts-checker-webpack-plugin already reads all required files (within an open pull request it even parses SFCs to get the script part) and does typescript magic on them, why not just reuse that file instead of reading and parsing it again.
-
Bootstrapping: Setting up a vue project with Typescript manually already needs so many different parts. Why introduce even more? Also we don't use any kind of task system like gulp or grunt as all we need is done by webpack in one config. This additional step would require much more additional configuration (for example in package.json in an ugly way for the build script).
-
Consistency: Using Vetur only in the frontend / IDE is not possible for larger projects. Type checking is an essential part and is required for CI. We need to be able to modify files via a basic editor and after commit the CI Build fails letting us know that we made a mistake instead of deploying unchecked and type broken code. Type checking and linting is already done by fork-ts-checker-webpack-plugin...couldn't this be intergrated there aswell?
...
It doesn't have a good place to surface diagnostics. I hate browser overlays for displaying errors. Editor is the most natural place to surface errors.
That is true for local development. Webpack however is not just a local development tool. It's an essential part to create a CI pipeline.
I have no idea how the template type checking is integrated into vetur but if it's possible I'd suggest to create an additional package that is only responsible for typechecking vue files by feeding it a typescript instance/session and the file/files you want to get diagnostics for (maybe some more infos that are needed). This way webpack loaders/plugins can make use of the same logic and also don't need to reimplement parsing of SFCs themself.
Does it work in relation between two vue components? Eg. passing the wrong type of prop from one to the other. I haven't been able to get that to work yet...
I was able to make this work via TSX syntax, but not in regular Vue files.
Will "type safety in templates during compile time" be a feature of the Vue 3 SFC compiler? I saw on the roadmap that it's being worked on now.
Eg. being notified by the Vue compiler when passing a string as a prop that can only be a number at compile time instead of during run time will be beneficial for all devs I believe. It will be easier to catch bugs without having to manually debug with a browser.
I published VTI (Vetur Terminal Interface). Feedback here: https://github.com/vuejs/vetur/issues/1635 You can use it this way:
npm i -g vti
# run this in the root of a Vue project
vti
vti diagnostics
@octref this is pretty cool. Can we make sure this is triggered via an npm script to make sure we cannot eg. commit things with errors.
eg. npm run vti && npm run build
and have it abort when there's an error.
@mesqueeb https://github.com/vuejs/vetur/issues/1640
It'll print all errors and exit with code 1:
The changes are published in 0.0.2. Note that this is not well-tested, and might not be very stable.
@octref this is so smart! It's the same as having type safety in templates as compile time! 😄 I very much appreciate all the hard work!
@yyx990803 ignoring Vetur, can you comment on whether TS support in Vue 3 will cover templates, specifically component invocations? Hypothetically if a component knows the types of its props, it should be able to fail at compile time if an invocation's attrs don't match up. I guess maybe that would require the template to also have a lang="ts"
equivalent?
@maxbogue unfortunately this can only be done via Vetur/VTI, since Vue's own compiler works on the template only and has no knowledge of type information.
Presumably it could be done as a plugin, like ForkTsCheckerWebpackPlugin
@yyx990803 Have you considered the possibility to emit TS code from the compiler as Angular does?
@cexbrayat technically the code emitted is already valid TS code, since the render function doesn't need any manual type hints.
I see a couple of old comments suggesting Vetur can take care of the type inference in the template. For VSCode users, there's also Volar that does this.
But, what about those of us who don't use VSCode? PHPStorm / Webstorm doesn't seem to cover this...
@Cry0nicS WebStorm will support it soon https://twitter.com/PiotrekTomiak/status/1429501676357132288