Ember-cli-typescript idea

I’m creating an addon that would allow typescript to be used in a project. The idea I have is that when ember build is run the source from typescript is 1st turned into es6 code and then things continue as usual. I would like to hear your opinions on the best way to integrate into the ember build process.

1 Like

I see that we used to do this in preprocessors.js, so back then perhaps I could just have added registry.add('js', 'broccoli-typescript', 'br');

  function addLegacyPreprocessors(registry) {
  registry.add('css', 'broccoli-stylus-single', 'styl');
  registry.add('css', 'broccoli-ruby-sass', ['scss', 'sass']);
  registry.add('css', 'broccoli-sass', ['scss', 'sass']);

  registry.add('minify-css', 'broccoli-csso', null);

  registry.add('js', 'broccoli-ember-script', 'em');

  registry.add('template', 'broccoli-emblem-compiler', ['embl', 'emblem']);
  registry.add('template', 'broccoli-ember-hbs-template-compiler', ['hbs', 'handlebars']);
}

I think @mixonic did some early work on this in the past, he may have some ideas

Great I hope to hear some if possible. Atm I will try achieve what I can with es6.

@Nikos there is a dedicated hook in ember-cli that lets your addon register a preprocessor. See https://github.com/ember-cli/ember-cli/blob/master/ADDON_HOOKS.md#setuppreprocessorregistry

@Nikos the biggest challenge when we looked at this last year was that the TypeScript transpiler had an extremely poor API. It also lacked any support for named AMD modules.

We eventually wrote a grunt processor that took the anonymous AMD output from the transpiler and added the appropriate module names.

You should note that TypeScript in an Ember codebase is not as useful as it might be in others. Specifically, the this.get and this.set based property interaction limits how automatic types can be. this.get could return anything at all, and so you are constantly specifying the returned type and rarely get to take advantage of all the static analysis.

Additionally Ember’s classes are their own system, and TypeScript does not understand inheritance or mixins in Ember. So again, you end up specifying types far more often than you might want to.

There is a DefinitelyTyped file for Ember, but keep in mind that is tracks no particular version of Ember, and may not have support for new syntaxes. We found ourselves mucking with it pretty often.

And lastly, we found the performance of the transpiler to be very poor. I hear this has improved though. In general, I think the best way to use TypeScript is in isolation. If you have a complex utility or library, you use TS for those sections and don’t feel the need to use it everywhere. Until JavaScript sports enough features that Ember can align with language APIs instead of needing its own, I’m not sure the benefits outweigh the significant costs.

@mixonic Thanks for the detailed rundown of the issues. For my use case I don’t actually want to generate ES6 for the ember code, I am happy as is, but would rather have a way to get tsc to compile a separate folder with the TS code into es6 before ember runs its build. The generated es6 would be what my ember app imports in the usual es6 manner. I don’t know how easy this is to do.

TypeScript has its own module system, and I am unsure if you can opt out of transpiling that one feature, or ask TS to output named modules. Remember that TS is a type-checker and transpiler in one big ball- the output is normally CJS or anonymous AMD ES5 code.

TypeScript support for ES6 modules is in alpha now and they will favor ES6 modules over their own convention once 1.5 lands.

It is recommended that TypeScript libraries and applications be updated to use the new syntax ES6 Modules · Issue #2242 · microsoft/TypeScript · GitHub

I’m unsure of whether or not they will officially deprecate their old system, but this should make some of the work easier.

@Nikos Good luck & awesome project, will be looking forward to seeing your progress here.

@kenkouot Great news! I’ll be keeping track of the 1.5 release and hopefully it will be simple to addon this as a preprocessor step before embers babel step which takes es6.

Looks like the latest release of TS supports what we need for this.

@Nikos I have been looking into flow myself recently and seems they made some progress in supporting ES6: https://github.com/facebook/flow/issues/287

So that might be interesting to look at as well, but haven’t had the chance yet to try it since they updated it.

Wow sounds cool, never head of flow.

Its a bit of a shot in the dark but I added this to my addon for index.js:

/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-typescript',
  setupPreprocessorRegistry: function(type, registry) {
    var self = this;

    registry.add('template', {
      name: 'broccoli-typescript',
      ext: 'ts'
      /*toTree: function(tree) {

        return htmlbarsCompile(tree, self.htmlbarsOptions());
      }*/
    });
  }
};

However I’m getting a compile error

Cannot read property 'apply' of undefined
TypeError: Cannot read property 'apply' of undefined
    at C:\Users\Laptop\WebstormProjects\ember-cli-typescript\node_modules\ember-cli\lib\preprocessors.js:186:25

Not sure what to try next without going deep into the CLI

@Nikos I got a working “ts to es6” ember-addon, you can check it out at https://github.com/KoKuToru/ember-typed
T̶h̶a̶t̶ ̶s̶a̶i̶d̶.̶.̶.̶ ̶i̶t̶’̶s̶ ̶n̶o̶t̶ ̶a̶b̶l̶e̶ ̶t̶o̶ ̶d̶i̶s̶p̶l̶a̶y̶ ̶e̶r̶r̶o̶r̶s̶.̶.̶.̶ ̶ :frowning:

Anyways, I did upload my typescript-experiment to github becaus e I saw this thread.
I would love to see a good TypeScript integration. :smiley:

Edit: it compiles ts correctly now, with errors etc.

1 Like

@KoKuToru wow nice, thanks for sharing, will check it out and see how you’ve done it!

I’m also very interested in Typescript. But I’m not sure if I want to use some typescript addon in production if there is no support by the core team. Or if there is no huge adoption in the community. Are there any plans to push Typescript or is the ember community more “wait-and-see” what happens with Typescript?

While I don’t expect Typescript to become standard for writing ember apps any time soon (if ever), there is growing interest in the community. Some of us have been experimenting with using it within some of Ember’s internals, and there is the start of a decent ember-cli-compatible typescript compiler plugin here: GitHub - tildeio/broccoli-typescript-compiler

I’m really interested in this. If Ember were using ES7 decorators and real TypeScript getters and settings (instead of their own type system), wouldn’t that circumvent the get(): any problem? Also, as I understand it, the long term goal of Ember is to use proper ES6 getters and settings right? I assume there is a discussion about this somewhere?

I am really into this concept after learning Swift and what a great type system can do for productivity and code quality.

Typed (actions) in templates would be amazing too…

1 Like

I also think that types are very helpful, but I also don’t think the Ember community will adopt it soon. With Ember CLI and Babel we already have a good development environment. Types would be a very nice extra feature.