Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static analyzing props using TSX/JSX #13

Closed
druppy opened this issue Nov 13, 2016 · 6 comments
Closed

Static analyzing props using TSX/JSX #13

druppy opened this issue Nov 13, 2016 · 6 comments

Comments

@druppy
Copy link

druppy commented Nov 13, 2016

As mentioned in the ts-loader issue list, it would be nice to think about making static analyse of properties while using TSX model and even when using .vue files. Please note that I am by no means no expert in either TypeScript, Vue nor WebPack, so please bear with me :-)

As I can see it, it should be possible, if the vue HTML template compiler output typescript code in stead if pure js (at least for all props arguments, the rest don't matter as it is auto generated code), and then make tsc compile all this together, to make the best use of all the good work done inside TS.

The problem with this is:

  • We need a vue.compile that optionally can generate typed props as arguments.
  • Error reporting will be good but we will have bad position data (has TS pragmas for line number changes like i C ?)
  • We need to make a TSX/vue loader, that can make this happen early, as tsc model for this is to make JS output, so we miss a lot of control.

So the flow could be :

  1. vue tsx split ->
  2. compile (pseudo) HTML part to render fn ->
  3. remerge autogen and original ts code ->
  4. compile it all using TSC (getting nice static errors)

Could this be done somehow ?

@HerringtonDarkholme
Copy link
Owner

HerringtonDarkholme commented Nov 14, 2016

Let me boil it down. It seems we have two approaches to achieve type safety in template, if it is what you asked in this issue.

  1. tsx approach
  2. transpiling template approach

The tsx approach is more promising. The basic idea is writing vue component in tsx, transform it to jsx by tsc, and finally transpile it to plain js by babel, using this plugin. This setup reuses all existing resources and is the easiest way to achieve partial safety in vue jsx.

Before we start, please first read this post to understand how tsx is checked. https://www.typescriptlang.org/docs/handbook/jsx.html

You first need to declare JSX namespace like this

declare namespace JSX {
  interface ElementAttributesProperty {
    props: ; // specify the property name to use
  }
}

Then you can declare vue's class.

import {Component, Vue} from 'av-ts'

@Component
class MyComponent extends Vue {
  // specify the property on the element instance type
  props: {
    foo: string;
  }
}

// element attributes type for 'MyComponent' is '{foo?: string}'
var a = <MyComponent foo="+1s" />

Over. All you can check is props and instance property reference in TSX. custom events/domProps/native events is not support. This is because tsx does not support prefix like on-click or domProps. But they are used by vue's babel transformer. https://github.com/vuejs/babel-plugin-transform-vue-jsx

@HerringtonDarkholme
Copy link
Owner

Now it's template transpiling approach. This pathway should achieve more integrated result, say, checking property access, props, events and semantic completion in template without compromising brevity and view-logic separation. Theoretically.

Practically this is an impossible approach. We need first reimplement vue's compiler and support expression parsing. More info here. vuejs/vue#4115 Evan did an amazing job to remove with. However, removing with requires patching Buble. Comparatively, we need to patch TypeScript compiler. Without microsoft/TypeScript#10160, it is almost impossible to catch up tsc's development which is developed by a full-time, talented team lead by one of programming language gods.

You can take a look at angular. They choose this approach, but does not work ideally. Currently angular forks typescript as ngc, and checking templates require another level of AOT compiling. And every thing is achieved by command line, which means you need another tooling layer like angular-cli or custom webpack loader. A lot of building system complexity. And this is Angular team's outcome! A full-time, highly talented team from Google™! And a lot of community contributors (361 contributors, as a comparison, Vue has 47).

As a hobby project, I don't think it can get sufficient support for template compiling. Yet, the benefits you get from template checking is small.

@druppy
Copy link
Author

druppy commented Nov 14, 2016

Firstly, thanks for your thoughtful analyze, it made it a bit more clear to me.

tsx/jsx files looks, as you say, more promising, and I hope the we soon will be able to skip the babel step too, but you summary makes it look even more attractive :-) I really should try to play more with this, and use .tsx files in stead of .vue, I mean ... we may not get every check, but we get quite a few.

I understand the template static compile problem (better now), and I guess that using tsx will again provide us with a much better solution than the vue model, in typescript context. Writing a complete compiler for things like that just don't make sense, as we don't gain anything the tsx don't provide us.

@HerringtonDarkholme
Copy link
Owner

I'm thinking about writing some render function helper to achieve similar type safety in plain TS. Something like this https://github.com/ktsn/vue-vnode-helper.

@HerringtonDarkholme
Copy link
Owner

Some idea about using vnode helper here. https://gist.github.com/HerringtonDarkholme/b3fccccf1abe7cde27686f613f53d55a

@druppy have you tried using vue's builtin createElement function to achieve type safety in template code? I wonder if it is a viable approach.

@HerringtonDarkholme
Copy link
Owner

For anyone interested, you can have a look on this.

https://github.com/HerringtonDarkholme/vivio

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants