The in-progress, experimental WVUI library is written in TypeScript, which was implemented after the evaluation completed in T249658. Now that the Design Systems Team is managing WVUI, we'd like to extend this evaluation and focus specifically on whether we should continue to use TypeScript in the library.
Disclaimer: I'm relatively new to TypeScript. Opinions from those who have used it a lot and those who are new to it are both appreciated.
Conclusion
"Codex", our new shared component library, will write Vue components in Typescript directly. You can see the current setup (subject to further refinement) here: https://github.com/wikimedia/vue-component-library/blob/main/packages/vue-components/tsconfig.json. The project is currently following the recommended configuration for Vite and Vue.js in TS.
In regards to the learning curve, we will work to provide documentation and help to contributors who are new to the language.
First, some notes
- WMDE uses TypeScript in Wikit, for reasons outlined in this decision record.
- There are various claims out there that attempt to quantify the benefit of using TypeScript or statically typed languages in general in terms of bug reduction: I've seen claims that using TypeScript can catch 15% or 20% of bugs, that TypeScript could have prevented 38% of bugs for Airbnb, and that statically typed languages have fewer bugs to a degree that is statistically significant but not functionally significant. All of these estimations have their flaws, so I'm not going to try including quantitative data in the pros or cons.
Benefits of TypeScript
There are some compelling reasons to use TypeScript, especially in a library like WVUI (and a future component library shared by more than just the Wikimedia Foundation), in terms of ease of maintenance, consistency of code in the long term, and IDE benefits for end users:
- Static typing
- More bugs are caught on code compilation, rather than at runtime
- In theory, refactoring and maintenance is easier
- Fewer tests needed since there is no need for additional testing of types
- Basically eliminates the need to catch type errors during code review (or worse, when debugging a production bug)
- More explicit typing
- Compared to JSDoc, types in TypeScript are much more specific and illustrative (e.g. an interface representing the exact shape of an object vs. Object)
- Incredibly robust IDE support
- Integration with VSCode provides code completion, hover info, signature info, and code snippets
- Code completion speeds up development (both of the library itself and for users of that library), less jumping to source files
- In addition to catching errors on compile, with a properly configured IDE, errors are evident immediately
- Better refactoring support
- Widely used in and loved by the greater front-end community
Downsides of using TypeScript:
- Creates a barrier to entry
- While TypeScript seems straightforward and sensible, getting the details of the syntax right in even moderately complex circumstances can be challenging and time-consuming. Though less code review is noted as a benefit above, the Design Systems Team has spent a non-trivial amount of time during code review trying to figure out how to properly use TypeScript in certain circumstances (e.g. in a Vue template)
- The code is more difficult to read for those who are not familiar with TypeScript
- TypeScript is not yet a common part of the MediaWiki ecosystem
- Configuration can be tricky, too, see this issue and resolution as an example from WMDE's Wikit
- Vue support of TypeScript isn't complete and is especially lacking in Vue 2
- Type checking in templates is relegated to Vetur (and is only experimental at the moment)
- Combining Vue prop types and TypeScript is clumsy, see the documentation
- Increases verbosity
- TypeScript code is objectively longer than JavaScript that does the same thing
- Can seem redundant or unnecessary
- Type definitions are supposed to be "self-documenting" but can occasionally be redundant and are sometimes no better than JSDoc
- Vue's PropTypes already offer static typing
Reducing the barrier
If we do decide to stick with TypeScript, we should think through ways to reduce the barrier to entry and to decrease time spent fighting with complex types and configuration. Some ideas:
- The combination of JSDoc and TypeScript can be confusing and seem redundant. For example, what if I use TypeScript to define the type of a function parameter, but I also need to add a brief sentence describing the param? Do I have to use both JSDoc and TypeScript? We should figure this out and come up with a documented standard to avoid confusion.
- Ensure that all of the configuration associated with TypeScript is complete, ideal, and maintainable
- Don't minimize the learning curve. When I did this research I came upon so many people saying that if you know JavaScript you already know TypeScript, that there's no learning curve, and that it's easy. That simply is not the case and isn't helpful to newcomers. Let's acknowledge the learning curve and provide ways for those new to TypeScript to onboard to it as painlessly as possible
- Make sure everyone is using the Vetur extension for VSCode