Des builds subséquentes plus rapides avec le drapeau --incrementalComme les fichiers TypeScript sont compilés, cela introduit une étape intermédiaire entre l'écriture et l'exécution de votre code. L'un des objectifs de Microsoft est de minimiser le temps passé en cas de modification de votre programme. Une façon de faire est d’exécuter TypeScript en mode --watch. Lorsqu’un fichier est modifié sous le mode --watch, TypeScript peut utiliser le graphe de dépendances précédemment construit de votre projet pour déterminer les fichiers susceptibles d’avoir été affectés et devant faire l’objet d’une nouvelle vérification et éventuellement d’une nouvelle émission. Cela peut éviter une vérification de type complète et une réémission qui peut être coûteuse.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // tsconfig.json { "compilerOptions": { "incremental": true, "outDir": "./lib" }, "include": ["./src"] } |
Ces fichiers .tsbuildinfo peuvent être supprimés en toute sécurité et n’ont aucune incidence sur notre code au moment de l’exécution - ils sont uniquement utilisés pour accélérer les compilations. Nous pouvons également leur attribuer le nom de notre choix et les placer où bon nous semble en utilisant le drapeau --tsBuildInfoFile.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | // front-end.tsconfig.json { "compilerOptions": { "incremental": true, "tsBuildInfoFile": "./buildcache/front-end", "outDir": "./lib" }, "include": ["./src"] } |
Projets composites
Une partie de l'intention avec les projets composites (tsconfig.jsons avec composite défini sur true) est que les références entre différents projets peuvent être générées de manière incrémentielle. En tant que tels, les projets composites produiront toujours des fichiers .tsbuildinfo.
outFile
Lorsque outFile est utilisé, le nom du fichier d’information de la build sera basé sur le nom du fichier de sortie. Par exemple, si notre fichier JavaScript de sortie est ./output/foo.js, sous l'indicateur --incremental, TypeScript générera le fichier ./output/foo.tsbuildinfo. Comme ci-dessus, cela peut être contrôlé avec l'indicateur --tsBuildInfoFile.
Le format de fichier --incremental et la gestion des versions
Bien que le fichier généré par --incremental soit JSON, le fichier n’est pas destiné à être utilisé par un autre outil. Microsoft ne peut donc fournir aucune garantie de stabilité pour son contenu et, en fait, sa politique actuelle est qu'une version quelconque de TypeScript ne comprendra pas les fichiers .tsbuildinfo générés à partir d'une autre version.
Améliorations pour les tuples ReadonlyArray et Readonly
TypeScript 3.4 facilite l'utilisation des types de type tableau en lecture seule.
Une nouvelle syntaxe pour ReadonlyArray
Le type ReadonlyArray décrit les tableaux pouvant uniquement être lus. Toute variable associée à un ReadonlyArray ne peut ajouter, supprimer ou remplacer aucun élément du tableau.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | function foo(arr: ReadonlyArray<string>) { arr.slice(); // okay arr.push("hello!"); // error! } |
TypeScript 3.4 introduit une nouvelle syntaxe pour ReadonlyArray en utilisant un nouveau modificateur readonly pour les types de tableau.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | function foo(arr: readonly string[]) { arr.slice(); // okay arr.push("hello!"); // error! } |
TypeScript 3.4 introduit également un nouveau support pour les tuples en lecture seule. Nous pouvons préfixer n'importe quel type de tuple avec le mot clé readonly pour en faire un tuple en lecture seule, un peu comme nous pouvons le faire avec la syntaxe abrégée de tableau. Comme vous vous en doutez, contrairement aux n-uplets ordinaires dans lesquels nous disposons de la possibilité d’écriture à des positions données, les n-uplets en lecture seule permettent uniquement de lire à partir de ces positions.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | function foo(pair: readonly [string, string]) { console.log(pair[0]); // okay pair[1] = "hello!"; // error } |
Dans les versions antérieures de TypeScript, Microsoft généralisait les types mappés pour qu'ils fonctionnent différemment sur les types de type tableau. Cela signifiait qu'un type mappé comme Boxify pouvait fonctionner sur les tableaux et les n-uplets.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | interface Box<T> { value: T } type Boxify<T> = { [K in keyof T]: Box<T[K]> } // { a: Box<string>, b: Box<number> } type A = Boxify<{ a: string, b: number }>; // Array<Box<number>> type B = Boxify<number[]>; // [Box<string>, Box<number>] type C = Boxify<[string, boolean]>; |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // lib.d.ts type Readonly<T> = { readonly [K in keyof T]: T[K] } // How code acted *before* TypeScript 3.4 // { readonly a: string, readonly b: number } type A = Readonly<{ a: string, b: number }>; // number[] type B = Readonly<number[]>; // [string, boolean] type C = Readonly<[string, boolean]>; |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | // How code acts now *with* TypeScript 3.4 // { readonly a: string, readonly b: number } type A = Readonly<{ a: string, b: number }>; // readonly number[] type B = Readonly<number[]>; // readonly [string, boolean] type C = Readonly<[string, boolean]>; |
De même, vous pouvez écrire un type d’utilitaire tel que le type mappé Writable qui supprime la lecture seule et convertit les conteneurs de tableaux en lecture seule en leurs équivalents mutables.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | type Writable<T> = { -readonly [K in keyof T]: T[K] } // { a: string, b: number } type A = Writable<{ readonly a: string; readonly b: number }>; // number[] type B = Writable<readonly number[]>; // [string, boolean] type C = Writable<readonly [string, boolean]>; |
Malgré son apparence, le modificateur de type readonly ne peut être utilisé que pour la syntaxe sur les types de tableaux et les types de tuples. Ce n'est pas un opérateur de type généraliste.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | let err1: readonly Set<number>; // error! let err2: readonly Array<boolean>; // error! let okay: readonly boolean[]; // works fine |
Lors de la déclaration d'une variable ou d'une propriété mutable, TypeScript élargit souvent les valeurs pour garantir que nous puissions affecter des éléments ultérieurement sans écrire de type explicite.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | let x = "hello"; // hurray! we can assign to 'x' later on! x = "world"; |
Une autre perspective pourrait être de dire que x a le type littéral original "hello" et que nous ne pouvons pas assigner "world" plus tard, comme ceci:
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | let x: "hello" = "hello"; // error! x = "world"; |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | type Shape = | { kind: "circle", radius: number } | { kind: "square", sideLength: number } function getShapes(): readonly Shape[] { let result = [ { kind: "circle", radius: 100, }, { kind: "square", sideLength: 50, }, ]; // Some terrible error message because TypeScript inferred // 'kind' to have the type 'string' instead of // either '"circle"' or '"square"'. return result; } |
Malheureusement, comme nous l'avons vu dans le dernier exemple, les propriétés en JavaScript sont mutables par défaut. Cela signifie que le langage élargira souvent les types de manière indésirable, nécessitant des types explicites à certains endroits.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | function getShapes(): readonly Shape[] { // This explicit annotation gives a hint // to avoid widening in the first place. let result: readonly Shape[] = [ { kind: "circle", radius: 100, }, { kind: "square", sideLength: 50, }, ]; return result; } |
Pour résoudre ce problème, TypeScript 3.4 introduit une nouvelle construction pour les valeurs littérales appelée assertions const. Sa syntaxe est une assertion de type avec const à la place du nom du type (par exemple, 123 en tant que const). Lorsque nous construisons de nouvelles expressions littérales avec des assertions const, nous pouvons signaler au langage que
- aucun type littéral dans cette expression ne doit être élargi (par exemple, pas de passage de "hello" à string)
- les littéraux d'objet obtiennent des propriétés en lecture seule
- les littéraux de tableau deviennent des tuples en lecture seule
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // Type '10' let x = 10 as const; // Type 'readonly [10, 20]' let y = [10, 20] as const; // Type '{ readonly text: "hello" }' let z = { text: "hello" } as const; Outside of .tsx files, the angle bracket assertion syntax can also be used. // Type '10' let x = <const>10; // Type 'readonly [10, 20]' let y = <const>[10, 20]; // Type '{ readonly text: "hello" }' let z = <const>{ text: "hello" }; |
Cette fonctionnalité signifie souvent que les types qui seraient autrement utilisés pour suggérer une immuabilité au compilateur peuvent souvent être omis.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Works with no types referenced or declared. // We only needed a single const assertion. function getShapes() { let result = [ { kind: "circle", radius: 100, }, { kind: "square", sideLength: 50, }, ] as const; return result; } for (const shape of getShapes()) { // Narrows perfectly! if (shape.kind === "circle") { console.log("Circle radius", shape.radius); } else { console.log("Square side length", shape.sideLength); } } |
Mises en garde
Une chose à noter est que les assertions const ne peuvent être appliquées immédiatement que sur des expressions littérales simples.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // Error! // A 'const' assertion can only be applied to a string, number, boolean, array, or object literal. let a = (Math.random() < 0.5 ? 0 : 1) as const; // Works! let b = Math.random() < 0.5 ? 0 as const : 1 as const; |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | let arr = [1, 2, 3, 4]; let foo = { name: "foo", contents: arr, }; foo.name = "bar"; // error! foo.contents = []; // error! foo.contents.push(5); // ...works! |
Il peut être étonnamment difficile d’accéder ou de déclarer des valeurs dans la portée globale, peut-être parce que nous écrivons notre code dans des modules (dont les déclarations locales ne fuient pas par défaut), ou parce que nous pourrions avoir une variable locale qui masque le nom d’une valeur globale. Dans différents environnements, il existe différentes manières d’accéder à ce qui est effectivement la portée globale (global dans Node, window, self, ou frames dans le navigateur), ou bien à certains endroits en dehors du mode strict. Rien de tout cela n’est évident et laisse souvent les utilisateurs incertains s’ils écrivent le code correct.
TypeScript 3.4 prend en charge la vérification de type du nouveau globalThis d’ECMAScript - une variable globale qui, ainsi, fait référence à la portée globale. À la différence des solutions ci-dessus, globalThis fournit un moyen standard d'accéder à l'étendue globale pouvant être utilisée dans différents environnements.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 | // in a global file: let abc = 100; // Refers to 'abc' from above. globalThis.abc = 200; |
| Code TypeScript : | Sélectionner tout |
1 2 3 | const answer = 42; globalThis.answer = 333333; // error! |
Convertir en paramètres nommés
Parfois, les listes de paramètres commencent à devenir difficiles à manier.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | function updateOptions( hue?: number, saturation?: number, brightness?: number, positionX?: number, positionY?: number positionZ?: number) { // .... } |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | interface Options { hue?: number, saturation?: number, brightness?: number, positionX?: number, positionY?: number positionZ?: number } function updateOptions(options: Options = {}) { // .... } |
Source : TyoeScript
Voir aussi :
VS Code : Microsoft annonce la disponibilité d'IntelliCode pour le développement TypeScript/JavaScript, et espère améliorer la productivité
Google s'oriente vers TypeScript et voici pourquoi, selon Evan Martin, un ingénieur de la firme qui travaille sur le langage
Babel : la version 7.0 du transpileur JavaScript est disponible avec le support de TypeScript et bien d'autres nouvelles fonctionnalités
TypeScript 2.9 est disponible et intègre plusieurs nouveautés, le langage continue de compléter son système de typage
Vous avez lu gratuitement 36 174 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.