Zoom sur les principales améliorations de TypeScript 2.2 :

Nouveau type primitif : object

Le type Object représente tout ce qui n’est pas du type : null | undefined.
Or dans certains cas on attend un objet et non une primitive ! C’est pour cela que le type object à été créé.
Le type object représente tout ce qui n’est pas du type : number | string | boolean | symbol | null | undefined.

Voyez cet exemple :

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

declare function fnOld(o: Object): void;
declare function fnNew(o: object): void;

// Type Object

fnOld({}); // OK
fnOld('obj'); // OK
fnOld(false); // OK

fnOld(null); // Error

// Type object

fnNew({}); // OK

fnNew('obj'); // Error
fnNew(false); // Error
fnNew(null); // Error

Cela va notamment permettre d’améliorer le static type check des fonctions natives qui attendent impérativement un objet en paramètre : Object.create(), Object.getOwnPropertyDescriptor(), …

Nouvelle façon d’accéder aux propriétés pour les types avec un index de type string

Un exemple est bien plus démonstratif dans ce cas :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

interface NumberDictionary {
[index: string]: number;
length: number;
}

const d: NumberDictionary;

//Avant

d["foo"] = 1; // OK
d.bar = 2; // Error

//Avec TypeScript 2.2

d["foo"] = 1; // OK
d.bar = 2; // OK

Support de new.target

Meta-propriété apparu dans la spec d’ES6, permet de savoir si notre constructeur ou fonction a été appelé avec le mot-clé new. Si oui, alors target obtient la référence du constructeur ou de la fonction appelée. Dans le cas contraire target vaut undefined.

new.target est désormais utilisable avec TypeScript grâce à la version 2.2 (static type check + transpilation ES3/ES5).

Mise à jour de __extends

Cette modification change la transpilation de l’héritage des propriétés statiques.

Pour transpiler l’héritage de classe de ES6 vers ES5/ES3 une fonction __extends est produite lors de la transpilation :

1
2
3
4
5
6

var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());

Cette fonction émule le comportement de l’héritage. Dans la fonction, le paramètre d hérite de b :

  1. Les propriétés possédées (‘own’) par b sont recopiées dans d
  2. Le prototype de d hérite du prototype de b (le prototype b devient son parent dans la chaîne des prototypes).

Maintenant voici la nouvelle fonction __extends générée par TypeScript 2.2 :

1
2
3
4
5
6
7
8
9
10
11
12

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 __());
};
})();

La grosse différence est l’utilisation de Object.setPrototypeOf (un fallback existe pour garder une compatibilité pour IE8, IE9 et IE10).

Grosso modo avec TypeScript 2.1, les membres statiques sont simplement copiés.
Avec TypeScript 2.2, les membres statiques sont hérités via la chaîne des prototypes.

Cela a deux impacts majeurs :

  • les propriétés héritées (2.2) ne sont pas ‘own’ alors que les propriétés copiées le sont (2.1).
  • changer une propriété héritée au runtime se répercutera dorénavant chez les héritiers !

Merci à @jods4 pour ses explications très détaillées sur le sujet.

Meilleur feedback sur d’éventuels erreurs dans le tsconfig.json

Pas besoin de détail pour cette feature je pense que le titre est assez explicite :)

Ajout de quick fixes

Fonctionnalité ajoutée dans le language service API depuis la 2.1, elle facilite la mise en place de suggestion dans nos IDE favoris pour corriger une erreur.
Dans cette version 2.2, quatre nouveaux quick fixes sont ajoutés : Add missing imports, Implement interface/abstract class members, Remove unused declarations et Add missing this.

Check de null/undefined dans les opérations

Amélioration du check d’opérande nullable dans les expressions ! Une opérande est considérée comme nullable si elle est de type null ou undefined ou un type union qui inclus null ou undefined. Voici pouvez trouver dans ce thread les cas impactés. Cette amélioration n’a d’intérêt que si l’option strictNullChecks est activée car dans le cas contraire null et undefined ne sont pas des types à part entier :)

Ceci n’est qu’une partie des nouveautés apportées par la version 2.2 de TypeScript ! Je n’ai pas abordé les améliorations pour JSX, la grosse avancée pour les mixins, …
Pour voir l’ensemble des apports : ici
On peut voir sur la roadmap que la version 2.3 est pévue pour mai 2017 avec notamment le support des generator pour ES3/ES5 !

A très vite :)