vue-loader icon indicating copy to clipboard operation
vue-loader copied to clipboard

Typescript type safety in `<template>`

Open blainehansen opened this issue 5 years ago • 12 comments

What problem does this feature solve?

When using typescript and the various helper libraries that help add types to components, you can get pretty robust type safety in the typescript code itself.

However, when actually using the properties of the component in the html template, the strict type safety is lost, and the only protection the developer has to ensure the safety of the template are the checks that the vue template compiler performs itself, or that various linters are able to make.

For a quick example of broken code:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <!-- this line will cause a runtime error, rather than being caught -->
    <!-- <p>{{ msg.someFakeFunction() }}</p> -->

    <!-- let's say these are both supposed to be numbers, -->
    <!-- that are going to be added together "get sum() { return this.a + this.b }" -->
    <!-- this won't cause a runtime error, but it will be surprisingly wrong -->
    <Sum :a="4" b="wrong!" />
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import Sum from './Sum.vue'

@Component({ components: { Sum } })
export default class HelloWorld extends Vue {
  @Prop() readonly msg!: string;
}
</script>

It would be very nice if, when using typescript as the script language for the component, the template was also compiled into some sort of typescript representation. This would necessarily mean that any other components used in the template would need to be typed, or they would be implicitly any.

The existing system already compiles templates to javascript render functions, so it seems like this would be possible. It could be added in a backwards-compatible way if the change was opt-in. Even though this change would detect many broken templates sitting around in people's code, they might not appreciate them no longer compiling.

Is the vue team is already working on something like this? Since vue 3 is being rewritten in typescript, you might already have this in the plan?

What does the proposed API look like?

There are two basic API additions I can think of that would allow people to opt in to this change:

  • An entirely different template compiler, that would be passed to vue-loader. It would probably make sense to use the existing one under the hood, but I'm not sure. This option would require that vue-loader give the compiler enough information to know if it should output typescript or not.
  • An option passed to the existing compiler, or to vue-loader as a whole. This could be as simple as something like generateTyped: boolean = false. The docs could explain that the template render functions will be typed only if the script alongside the template is also in typescript.

It seems this is at least somewhat on people's minds. It would be nice to not have to roll hacky loaders like this one. Deeper type safety is always a nice thing to have for the people who are searching for it.

I haven't looked deeply into what this might require, but I would be happy to contribute code to this if it's a welcome addition. I would also be happy to come up with the final API additions after figuring out how any existing code would have to change.

Thanks!

blainehansen avatar Jun 21 '19 20:06 blainehansen

add typescript-loader into vue.config.js or try to use <script src="some.ts"></script> and transpile u'r *.ts

cybermerlin avatar Jul 15 '19 10:07 cybermerlin

@blainehansen , btw, be careful, ur task created not by guideline =)

cybermerlin avatar Jul 15 '19 10:07 cybermerlin

I think compile time validation of props is a crucial thing for large projects. It's good that Vue has own props validation system, but it works only on run time.

kryvonos-v avatar Jul 16 '19 10:07 kryvonos-v

See https://github.com/vuejs/rfcs/issues/64#issuecomment-505717497 We are going to leverage Vetur to do the template type checking. Keep an eye on its development.

sodatea avatar Jul 24 '19 06:07 sodatea

@sodatea Is it only for VS Code? Or at compile time too?

trusktr avatar Jul 24 '19 22:07 trusktr

@trusktr Please follow the link and read the discussions there.

sodatea avatar Jul 25 '19 02:07 sodatea

https://github.com/Yuyz0112/vue-type-check For people who need this, I have made a simple CLI that port the vetur's template type-checking feature.

Yuyz0112 avatar Oct 11 '19 05:10 Yuyz0112

@Yuyz0112 does it work with vue-property-decorator?

Djaler avatar Jan 03 '20 19:01 Djaler

@Djaler I think yes.

Yuyz0112 avatar Jan 04 '20 05:01 Yuyz0112

Only adding this to Vetur, doesn't seem like a good idea. Passing option to enable this to the vue-loader sounds a lot more widely usable. The vetur implementation will be an island... I don't use Vetur and I don't think it is in the best interest of the entire community to add such a crucial feature only for one tool and not the actual compiler/ compilation infrastructure... After all this is the main reason people choose typescript for type safety at compile time. Solving the problem with a linter or grammar check tool, sounds more like a hack...

guslen avatar Sep 20 '20 10:09 guslen

Are there any news on this?

Blackfaded avatar Jan 25 '21 16:01 Blackfaded

We had few misalignments in the team with Vetur not being configured perfectly by a few folks, so I took the week-end to write a small Webpack plugin that checks templates against the type of components.

It's only working with the next version of @vue/cli-service (5.0, it's beta now!) and requires Webpack 5, but it's working pretty well over here.

You can find it on NPM as @juit/vue-ts-checker

I'd appreciate some feedback via GitHub (feel free to open issues)

pfumagalli avatar May 16 '21 22:05 pfumagalli

It wasn't achieved in this repo, but the work the vue team has done building vue-tsc, and just generally prioritizing typescript in the design of vue 3 and the script setup system has made the type safety experience of vue frankly superlative. I genuinely think I'd have to go to a completely different language to have a more rigorously checkable application!

The fact that I can enjoy such flexible concepts as scoped slots and still have complete checking is awesome :) Just wanted to let the team know their work is appreciated!

blainehansen avatar Mar 12 '24 04:03 blainehansen