It must be acknowledged that 2.x’s TS support is obviously a bit different from React and Angular support, which is why 3.0 will strengthen it.
For current implementations of 2.x with TS, it is usually necessary to write class-based components based on vue-class-Component. There is support for type inference for the default way objects are written, but the implementation takes many twists and turns. The nature of the problem is simple: the API was designed without a type system in mind.
When Vue was first written five and a half years ago JS had no type system at all, and I myself didn’t use a type language at the time, so the Vue component was essentially an “object with options to describe the component”. This design is a typical intuition based design. It is designed not from the mechanism of language itself or type system, but simply from how people describe what they want. The advantage of such a design is that it is easy for beginners to understand, but the drawback is that there is a real “disconnect” between the type system. Just how significant this disconnect is varies for different types of users. First of all, because the API is fairly straightforward, most people get used to it pretty quickly, even though it mismatches traditional OO. For users who don’t use the type system and are more concerned with component business logic, this disconnect is actually invisible. Second, the fault lines here work both ways: you could say that Vue’s API design is not type friendly, or conversely that TS’s type system is not powerful enough to support Vue well enough. One example is that JSX didn’t have any type support in the first place, and it was TS who imposed a whole set of derivation mechanisms for JSX that gave TSX its current development experience. If TS is not supported because JSX is not a true JS specification, is there a disconnect between the React design and type system?
A more straightforward way to bridge this gap, of course, is to redesign the API. Simple enough to say, but for Vue, there are a number of things to consider when changing an API:
- Compatibility with legacy apis: Can both old and new apis be supported? How can old users be upgraded? It’s easy to change as Angular does, but it’s straightforward to leave old users dead.
- How do you design something that provides good type derivation without leaking design for type’s sake into the experience of non-TS users? How to achieve the best consistency and balance between TS and non-TS experience? Again, it would certainly be easier to leave non-TS users dead like Angular does, but we won’t do that.
- Native support for class is not ideal: using class as the default API too early means users won’t be able to use it in some browsers without pre-compiling, something we’ve been trying to avoid. Vue has always valued the “bring in a script and start writing” use case because it ensures a minimum barrier to entry for newcomers and makes it easy to integrate Vue into legacy applications as an alternative to jQuery. So there’s a timing issue with changing the API, it’s too early.
- Class fields, decorators, etc., on which components depend to write in class are not yet available: The proposal design API based on Stage <4 is very risky. For example, the default semantics of class fields are [[Set]], which is changed to [[Define]] by Stage 3. Because they have an API design that relies entirely on class Fields’ [[Set]] semantics. The Decorators proposal has been completely redesigned, and the recent TC39 attempt to move to stage 3 was rejected by the V8 team due to performance concerns, and may have to be overhauled again; There is still a debate about whether decorators should come before export, and Angular’s Igor is in a rush… So, how do you avoid embarrassing yourself by designing an API that has to change after the proposal changes? (I was actually invited to talk about these things, but talking about specifications is incredibly time consuming and often doesn’t convince many people…)
A little extra talk about templates and type derivation. On the surface, there seems to be a “gap” between template syntax and compilation, but in fact there is not as far as you think. The Vue template is compiled into the Virtual DOM rendering function, and the generated JS can be typed derivable just like the React rendering function. There is a complete logical mapping between the template and the generated JS, so it is mainly necessary to make some connection in the tool chain. Intellisense from the analysis of the generated JS is fed back to the template in the IDE. It’s technically completely feasible.
There’s another part of the answer that says React’s JS base makes it easy to do multiple rendering, which isn’t true. Multiple rendering essentially requires the runtime to do core and platform separation from the start. Vue 2 does this from the beginning (hence weex, NativeScript Vue, etc.). In fact, there is a template which is a much simpler compilation source and has a little more flexibility to do multiple applications. mpvue, megalo, uni-app…
What type system Vue itself uses for its internal implementation is another question. The key to the user’s experience of using TS to write Vue is in the API. Using TS as an internal implementation actually only reduces the cost of additional maintenance of D. TS. As for why WE didn’t use TS at the beginning, I believe many of you have read my previous answer. Who would have thought that the Flow team would be so lame? The TS team, by contrast, really put their minds to it. Daniel Rosenwasser (PM of TS) has communicated with me many times and even attended VueConf. He has become an acquaintance.
To sum up:
- The combination of the existing API and type system is flawed and left over from history; There is a timing issue with the new API, please be patient for Vue 3;
- TSX type support is good because OF the special backdoor support for TS; Templates can be done as long as the tool chain is in place.
- Vue 2 had a type system from the beginning, but Flow was dead, and the TS ecosystem was getting better and better. This belongs to the wrong treasure, can only say… delicious