Evaluate TypeScript

Evaluate TypeScript

I used the template of the Ember.js RFC to document this issue. I think it is a good template to adress the main concerns about a bigger change. For details about their RFC process you can visit their github repo: https://github.com/emberjs/rfcs

Summary

I wanted to move all the TypeScript discussions into one single place, because right now all the pros and cons about TypeScript are scattred around several issues, threads, pull requests and discussions. This makes it very hard to follow and I think there won’t be any significant progress if we do not focus. Also I think there is a lot of traction concerning three.js and TypeScript as seen lately in #11552

Motivation

Since TypeScript becomes more and more popular in the frontend community we could start thinking about adoption. Also if you compare the weekly downloads of @types/three and the three package on npm it seems that a lot of people use Three.js already with TypeScript. For the time frame 2019-01-01 to 2019-01-07 it was 56414 downloads of three and 40588 for @types/three (for more details see: https://www.npmjs.com/package/@types/three and https://www.npmjs.com/package/three). Furthermore there is already a lot of work done spread across several projects and repositories. Therefore it would be nice to join forces and maintain the TypeScript stuff in one place.

In my opinon there are more pros than cons for TypeScript (but of course there are a lot of controversial opinions about types in JavaScript and TypeScript in special in the community)

Some of pros I see are:

  • possibility to improve developer experience, also for new contributors and for users of the Three library
  • types could help to explorer the api of the Three library and they could help to develop with less need to read the docs
  • no out dated @types/three definitions anymore
  • room for future transpile optimizations (for example things like tsickle is doing right, I think there will be more tools like this in future). Also experimental tools like AssemblyScript could become an option for certain very performance critic parts of the source code
  • types could help to improve code quality
  • possibility to use new features of the ECMAScript standard and transpile the source to different ECMAScript versions
  • when done right it makes no difference for the users of the Three library if the source code is maintained in TS or JS
  • with the compiler flag declarationDir we are able to generate the d.ts files from our source code so all typings are always up to date

Detailed design

We should finish all the ES6 efforts first since they form the base for TypeScript. Also the transition from ES6 to TypeScript wouldn’t be that hard (since TypeScript reads a lot like modern JavaScript with types). To start with TypeScript we just need to add the rollup-plugin-typescript (I would suggest rollup-plugin-typescript2). Then we need to create a tsconfig.json and setup all the TypeScript-compiler settings to our needs. Maybe we should add tslint as well (there is also a rollup plugin for that, it’s called rollup-plugin-tslint). After the build works we could incorporate the typings done in @types/three and other projects like three.ts.

How we teach this

At first we would need to document it correclty for new contributors. For the users of Three.js everything stays the same (since TypeScript is transpiled to JavaScript). After some iterations it would make sense to provide the code examples in the docs in TypeScript and JavaScript. A good example how this could be done is the Stripe API docu

Drawbacks

The build pipeline becomes more complicated and more dependencies are added. Furthermore I’m not sure how easy it is to migrate the test suite and the test runner. Also the entry barrier for new contributors (not for users of the library) could become higher since they need to know TypeScript. Very generic code can become very verbose when adding types. With TypeScript we are a little bit more away of “the platform” since there is a transpile step inbetween and we are not in total control of transpilation (of course we could write our own transforms but this is very tedious)

Alternatives

Just stick with pure JavaScript but this would also mean that we neglect all the efforts already done by projects like @types/three. For all the users of Three.js with TypeScript this would mean that they need to rely on an unofficial typing of Three.

Unresolved questions

  • Do we really want this?
  • When to start (right now or after ES6 finalization)?
  • How to start? Should we start at first only with d.ts files or jump fully into TypeScript?
  • Who could do this or let me phrase it differently, who is motivated to start this?

Author: Fantashit

7 thoughts on “Evaluate TypeScript

  1. From the view of runtime performance, I’m interested in

    Also experimental tools like AssemblyScript could become an option for certain very performance critic parts of the source code

    I’ve been doing Three.js core + WASM experimentation.

    https://github.com/takahirox/three.wasm-experimental
    https://twitter.com/superhoge/status/1071132448426262529

    From the experimentation I realized porting the entire core to WASM can improve the runtime performance, 1.5x faster on my example, while partially porting the small parts, for example just Math codes(Vector3, Matrix4, …), is no benefit because of big JS-WASM overhead.

    But I didn’t think it’s a good idea to rewrite the entire Three.js core into C++ or Rust for contributors because of difficulty of maintenance so I’ve been looking for alternative ways. I’m interested in if TypeScript + AssemblyScript works fine for Three.js.

  2. How to start? Should we start at first only with d.ts files or jump fully into TypeScript?

    We will be submitting a PR that adds *.d.ts files to Three.JS, based primarily on @types/three (thus reusing that work.) That is a great starting point and lets us continue in JS for now. It can also be done incrementally.

  3. @tschoartschi I’d like to move this issue forward. @mrdoob has approved side-by-side *.d.ts files. I’d like to go there because it doesn’t force TypeScript on people immediately and we can back out of it without having to rewrite all contributions during the *.ts phase. And then we can still convert *.js files to *.ts files incrementally mostly my merging them with the side-by-side *.d.ts files.

    I think that side-by-side *.d.ts files is a really good first step and it is easy to do. I would prefer to not allow “perfection” to hold us back from making incremental progress.

  4. Until browsers do not support TypeScript natively I prefer to focus on JavaScript ES6.

    I understand it can be compiled to .js, but we’re just starting to be able to import from src directly and I think that’s going to help the project more than converting to TypeScript.

    https://github.com/mrdoob/three.js/blob/dev/examples/webgl2_sandbox.html#L37-L48

    Adding side-by-side *.d.ts files sounds good but it’ll need someone to own it and keep them up to date.

  5. Just another suggestion:
    The Phaser game framework uses its comments to auto generate type definitions. I think the tool is opensourced. So TS definitions could be generated by adding /** comments */ above the functions in the correct manner.

  6. Sidenote: TypeScript in browsers may not be far off if Deno (A TypeScript interpreter built on V8 and Rust with 32,000 stars on GitHub) proves to be worthy.

  7. Since we added type declaration files for the core and the example modules, I think it’s okay to close the issue for now. The development experience for TS users should be definitely better than last year.

Comments are closed.