Nouvelle option --strict

Elle permet d’activer automatiquement les quatres options suivantes :

Cette option dite ‘maître’, a pour but d’activer un haut niveau de contrôle des types et active donc les options nécessaires. Elle est activée par defaut lorsqu’on initialise un tsconfig.json via l’invite de commande tsc. Dans les prochaines versions de TypeScript probablement que d’autres options seront activées via cette option ‘maître’.

Amélioration du tsconfig.json par défaut

La commande tsc --init permet de générer un tsconfig.json pour démarrer un projet TypeScript.

Avant la 2.3 voila ce que la commande générait :

1
2
3
4
5
6
7
8
9
10

{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
}
}

Pour obtenir des informations sur les autres options, obligé de passer par la documentation sur le site officiel. Avec la 2.3, on tape la même commande :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
// "lib": [], /* Specify library files to be included in the compilation: */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */

/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */

/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */

/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}

De même vous pouvez afficher l’ensemble des options utilisables avec la ligne de commande : tsc --help --all

Générateur et Itérateur pour ES5/ES3

La proposition de cette feature date de décembre 2014 ! Depuis la 1.6, TypeScript supporte de façon très basique les generateurs lorsqu’on transpile de l’ES6. Si on souhaitais cibler ES5 il fallait trouver une alternative, par exemple le polyfill de Facebook nommé regenator.

Grâce à la nouvelle option de compilation –downlevelIteration il est désormais possible de cibler ES5/ES3 et d’utiliser les générateurs et itérateurs dans notre code. Le typage pour les generateurs à évidement été bien poussé et c’est ce qui à pris pas mal de temps.

Petite subtilité : lors de l’utilisation de cette option, il faut impérativement fournir un shim pour la méthode Symbol.iterator ou qu’elle existe nativement au sein du navigateur ciblé. En effet, le compilateur va tenter d’appeler cette méthode sur les objets sur lesquelles on itères !

Point d’extention de la brique Language Service

Pour bien comprendre l’enjeu de cette nouveauté il faut comprendre grosso-modo la façon dont est architecturé TypeScript.

Voici un aperçu macro de l’architecture :

architecture TypeScript

La brique qui nous intéresse ici est Language Service. Cette brique wrap le compilateur et expose des services déstinés aux IDE : auto-complétion, colorisation, re-factoring, …

Pourquoi vouloir utiliser les services frounis par cette brique ? Eh bien pour apporter ces features pour d’autres langages que le JS. Par exemple pour avoir ces features avec les templates d’angular 2 ou encore pour les templates de vueJs. Voici une démo d’Angular Language Service :

Démo Angular Language Service

Avant la 2.3, les languages services adapter pour les templates angular par exemple, étaient séparés du TypeScript utilisé par l’IDE et utilisaient donc une version dupliquée…

Avec la 2.3, cela devient très facile d’intégrer ces plugins sans dupliquer TypeScript, il suffit de modifier son tsconfig.json :

1
2
3
4
5
6
7
8
{
"compilerOptions": {
"plugins": [
{ "name": "tslint-language-service"},
{ "name": "@angular/language-service"}
]
}
}

Pour ceux qui souhaite profiter de ces plugins sans la version 2.3 il existe une alternative.

Pour en savoir plus, le thread qui parle du problème et la proposition (avec une très belle explication du nouveau pipeline !)

Nouvelle option –checkJs

Utilisée conjointement avec l’option –allowJs, elle permet de checker vos fichiers javascript tout comme si c’était des fichiers .ts.

Des flag sous forme de commentaires (à placer en tête des fichiers) permettent de controller quel fichier est à checker : // @ts-nocheck et // @ts-check.
Il est également possible de désactiver le check d’une ligne précise avec // @ts-ignore.

Le check des fichiers .js ne vérifie que l’utilisation convenable des features définies par l’ECMASCRIPT. Les annotations de types reste propre aux fichiers .ts et seront marquées comme erreur dans les fichiers .js

Une alternative pour utiliser l’annotation de type dans vos fichiers .js est l’utilisation de la JsDoc dont vous pouvez voir le support ici.

Pour voir la liste complète des nouveautés direction la roadmap.

A très vite :)