Explication

Lorsque Typescript transpile de l’ES6 vers une version inférieur (ES5 ou ES3), il génère des fonctions helpers (ou polyfill) pour émuler des fonctionnalités non implémentés dans certain navigateur. Par exemple lorsqu’on utilise le mot-clé extends :

1
2
3
4
5
6
7
8
9

class Foo {
constructor() { }
}

class Bar extends Foo {
constructor() { super(); }
}

TypeScript génère :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var Foo = (function () {
function Foo() {
}
return Foo;
}());
var Bar = (function (_super) {
__extends(Bar, _super);
function Bar() {
return _super.call(this) || this;
}
return Bar;
}(Foo));

Il existe un tas d’autre polyfill utilisé par TypeScript :

1
2
3
4
5
6
7

function __assign(t: any, ...sources: any[]): any; // Polyfill de Object.Assign
function __rest(t: any, propertyNames: (string | symbol)[]): any; // Polyfill d'un paramètre rest
function __spread(...args: any[]): any[]; // Polyfill de l'opérateur spread

//...

Bon jusqu’ici rien d’anormal, mais le gros problème, c’est que ces polyfill sont générées dans chaque fichier où ils sont référencés ! Donc si j’ai 10 fichiers ou j’utilise le mot-clé extend, hé bien le polyfill sera généré dans les 10 fichiers :(

Depuis la version 1.8 de TypeScript, l’option de compilation --noEmitHelpers à été introduite. Elle permet de ne plus générer ces polyfill. Cela permet d’avoir package npm contenant l’ensemble des polyfill (utilisé par TypeScript) et de ne l’importer qu’une seule fois (ce que proposait le package ts-helpers). Le soucis majeur de cette solution est qu’il n’existait pas de package officiel maintenu par l’équipe de TypeScript et qu’il fallait nous-même importer ce package…

Plus ce genre de soucis depuis l’arrivé de la 2.1 ! Première bonne nouvelle, un package officiel existe désormais et est maintenant par l’équipe de TypeScript : tslib. Deuxième good news, plus besoin d’importer nous-même le package grâce à l’option de compilation --importHelpers qui s’en charge à notre place.

Mise en place

Il vous suffit d’installer la lib tslib :

1
2
3

npm install tslib

Puis d’avoir les options noEmitHelpers et importHelpers à true dans votre tsconfig.json :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"pretty": true,
"noEmitHelpers": true,
"importHelpers": true
},
"exclude": [
"node_modules"
]
}

Et c’est tout !

Le thread de discussion sur Github : thread

A bientôt :)