Code : | Sélectionner tout |
npm install -D typescript@beta
- Attributs d'importation
- Stable Support resolution-mode dans les types d'importation
- switch (true) Rétrécissement
- Rétrécissement sur les comparaisons avec les booléens
- instanceof Narrowing Through Symbol.hasInstance
- Vérifie les accès aux super propriétés sur les champs d'instance
- Indices d'incrustation interactifs pour les types
- Optimisations en sautant l'analyse JSDoc
- Optimisation par comparaison d'intersections non normalisées
- Consolidation entre tsserverlibrary.js et typescript.js
- Changements de rupture et améliorations de la correction
Attributs d'importation
TypeScript 5.3 prend en charge les dernières mises à jour de la proposition relative aux attributs d'importation.
L'un des cas d'utilisation des attributs d'importation est de fournir des informations sur le format attendu d'un module au moteur d'exécution.
Code : | Sélectionner tout |
1 2 3 | // We only want this to be interpreted as JSON, // not a runnable/malicious JavaScript file with a `.json` extension. import obj from "./something.json" with { type: "json" }; |
Le contenu de ces attributs n'est pas vérifié par TypeScript puisqu'ils sont spécifiques à l'hôte, et sont simplement laissés en l'état pour que les navigateurs et les moteurs d'exécution puissent les gérer (et éventuellement commettre des erreurs).
Code : | Sélectionner tout |
1 2 3 | // TypeScript is fine with this. // But your browser? Probably not. import * as foo from "./foo.js" with { type: "fluffy bunny" }; |
Code : | Sélectionner tout |
1 2 3 | const obj = await import("./something.json", { with: { type: "json" } }); |
Notez que les attributs d'importation sont une évolution d'une proposition antérieure appelée "assertions d'importation", qui a été mise en œuvre dans TypeScript 4.5. La différence la plus évidente est l'utilisation du mot-clé with au lieu du mot-clé assert. Mais la différence la moins visible est que les moteurs d'exécution sont désormais libres d'utiliser les attributs pour guider la résolution et l'interprétation des chemins d'importation, alors que les assertions d'importation ne pouvaient affirmer certaines caractéristiques qu'après le chargement d'un module.
Au fil du temps, TypeScript abandonnera l'ancienne syntaxe des assertions d'importation au profit de la syntaxe proposée pour les attributs d'importation. Le code existant utilisant assertdevrait migrer vers le mot-clé with. Le nouveau code qui a besoin d'un attribut d'importation devrait utiliser exclusivement with.
Prise en charge stable du résolution-modedans les types d'importation
Dans TypeScript 4.7, TypeScript a ajouté le support d'un attribut resolution-mode dans /// <reference types="..." /> pour contrôler si un spécificateur doit être résolu via importou requiresémantics.
Code : | Sélectionner tout |
1 2 3 4 5 | /// <reference types="pkg" resolution-mode="require" /> // or /// <reference types="pkg" resolution-mode="import" /> |
Mais étant donné que les attributs d'importation peuvent guider la résolution, et que nous avons vu des cas d'utilisation raisonnables, TypeScript 5.3 supporte maintenant l'attribut resolution-modepour le import type.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | // Resolve `pkg` as if we were importing with a `require()` import type { TypeFromRequire } from "pkg" with { "resolution-mode": "require" }; // Resolve `pkg` as if we were importing with an `import` import type { TypeFromImport } from "pkg" with { "resolution-mode": "import" }; export interface MergedType extends TypeFromRequire, TypeFromImport {} |
Ces attributs d'importation peuvent également être utilisés pour les import() types.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | export type TypeFromRequire = import("pkg", { with: { "resolution-mode": "require" } }).TypeFromRequire; export type TypeFromImport = import("pkg", { with: { "resolution-mode": "import" } }).TypeFromImport; export interface MergedType extends TypeFromRequire, TypeFromImport {} |
TypeScript 5.3 peut désormais effectuer un rétrécissement basé sur des conditions dans chaque case clause à l'intérieur switch (true).
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function f(x: unknown) { switch (true) { case typeof x === "string": // 'x' is a 'string' here console.log(x.toUpperCase()); // falls through... case Array.isArray(x): // 'x' is a 'string | any[]' here. console.log(x.length); // falls through... default: // 'x' is 'unknown' here. // ... } } |
Il peut arriver que vous ayez à effectuer une comparaison directe avec trueou false dans une condition. Il s'agit généralement de comparaisons inutiles, mais vous pouvez les préférer pour des raisons de style ou pour éviter certains problèmes liés à la véracité de JavaScript. Quoi qu'il en soit, TypeScript ne reconnaissait pas ces formes lorsqu'il effectuait un rétrécissement.
TypeScript 5.3 se met désormais au diapason et comprend ces expressions lors du rétrécissement des variables.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | interface A { a: string; } interface B { b: string; } type MyType = A | B; function isA(x: MyType): x is A { return "a" in x; } function someFn(x: MyType) { if (isA(x) === true) { console.log(x.a); // works! } } |
Une caractéristique légèrement ésotérique de JavaScript est qu'il est possible d'outrepasser le comportement de l'opérateur instanceof. Pour ce faire, la valeur à droite de l'opérateur instanceofdoit avoir une méthode spécifique nommée par Symbol.hasInstance.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | class Weirdo { static [Symbol.hasInstance](testedValue) { // wait, what? return testedValue === undefined; } } // false console.log(new Thing() instanceof Weirdo); // true console.log(undefined instanceof Weirdo); |
Code : | Sélectionner tout |
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 | interface PointLike { x: number; y: number; } class Point implements PointLike { x: number; y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } distanceFromOrigin() { return Math.sqrt(this.x ** 2 + this.y ** 2); } static [Symbol.hasInstance](val: unknown): val is PointLike { return !!val && typeof val === "object" && "x" in val && "y" in val && typeof val.x === "number" && typeof val.y === "number"; } } function f(value: unknown) { if (value instanceof Point) { // Can access both of these - correct! value.x; value.y; // Can't access this - we have a 'PointLike', // but we don't *actually* have a 'Point'. value.distanceFromOrigin(); } } |
Vérification des accès à la propriété supersur les champs d'instance
En JavaScript, il est possible d'accéder à une déclaration dans une classe de base grâce au mot-clé super.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Base { someMethod() { console.log("Base method called!"); } } class Derived extends Base { someMethod() { console.log("Derived method called!"); super.someMethod(); } } new Derived().someMethod(); // Prints: // Derived method called! // Base method called! |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Base { someMethod() { console.log("someMethod called!"); } } class Derived extends Base { someOtherMethod() { // These act identically. this.someMethod(); super.someMethod(); } } new Derived().someOtherMethod(); // Prints: // someMethod called! // someMethod called! |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Base { someMethod = () => { console.log("someMethod called!"); } } class Derived extends Base { someOtherMethod() { super.someMethod(); } } new Derived().someOtherMethod(); // 💥 // Doesn't work because 'super.someMethod' is 'undefined'. |
Indices d'incrustation interactifs pour les types
Les indices d'incrustation de TypeScript permettent désormais de sauter à la définition des types ! Cela facilite la navigation dans votre code.
Optimisations en ignorant l'analyse JSDoc
Lors de l'exécution de TypeScript via tsc, le compilateur évitera désormais d'analyser JSDoc. Cela réduit le temps d'analyse en soi, mais réduit également l'utilisation de la mémoire pour stocker les commentaires ainsi que le temps passé dans le garbage collection. Dans l'ensemble, vous devriez voir des compilations légèrement plus rapides et un retour d'information plus rapide en mode --watch.
Parce que tous les outils utilisant TypeScript n'auront pas besoin de stocker JSDoc (par exemple, typescript-eslint et Prettier), cette stratégie d'analyse a été présentée comme faisant partie de l'API elle-même. Cela peut permettre à ces outils de bénéficier des mêmes améliorations en termes de mémoire et de vitesse que celles que Microsoft a apportées au compilateur TypeScript. Les nouvelles options pour la stratégie d'analyse des commentaires sont décrites dans JSDocParsingMode.
Optimisations par comparaison d'intersections non normalisées
En TypeScript, les unions et les intersections suivent toujours une forme spécifique, où les intersections ne peuvent pas contenir de types d'union. Cela signifie que lorsque nous créons une intersection sur une union comme A & (B | C), cette intersection sera normalisée en (A & B) | (A & C). Cependant, dans certains cas, le système de types conservera la forme originale à des fins d'affichage.
Il s'avère que la forme originale peut être utilisée pour des comparaisons rapides et astucieuses entre les types.
Par exemple, disons que nous avons un someType & (Type1 | Type2 | ... | Type99999NINE) et que nous voulons voir s'il est assignable à un someType . Rappelons que nous n'avons pas vraiment d'intersection comme type source - nous avons une union qui ressemble à (UnType & Type1) | (UnType & Type2) | ... ... |(UnType & Type99999NINE). Lorsqu'on vérifie si une union est assignable à un type cible, on doit vérifier si chaque membre de l'union est assignable au type cible, ce qui peut être très lent.
Consolidation entre tsserverlibrary.jset typescript.js
TypeScript est livré avec deux fichiers de bibliothèque : tsserverlibrary.js et typescript.js. Certaines API ne sont disponibles que dans tsserverlibrary.js (comme l'API ProjectService), ce qui peut être utile à certains importateurs. Cependant, les deux paquets sont distincts et se chevauchent beaucoup, dupliquant le code dans le paquet. De plus, il peut être difficile d'utiliser systématiquement l'un plutôt que l'autre en raison des importations automatiques ou de la mémoire musculaire. Il est beaucoup trop facile de charger accidentellement les deux modules, et le code peut ne pas fonctionner correctement sur une instance différente de l'API. Même s'il fonctionne, le chargement d'un second bundle augmente l'utilisation des ressources.
Dans ces conditions, Microsoft a décidé de consolider les deux modules. typescript.jscontient maintenant ce que tsserverlibrary.js contenait auparavant, et tsserverlibrary.jsré-exporte simplement typescript.js. En comparant l'avant/après de cette consolidation, Microsoft a constaté la réduction suivante de la taille des paquets :
En d'autres termes, il s'agit d'une réduction de plus de 20,5 % de la taille de l'emballage.
Changements de rupture et améliorations de la correction
Changements dans lib.d.ts
Les types générés pour le DOM peuvent avoir un impact sur votre base de code.
Vérification des superaccès aux propriétés d'instance
TypeScript 5.3 détecte maintenant quand la déclaration référencée par un accès à la propriété super. est un champ de classe et émet une erreur. Cela permet d'éviter les erreurs qui pourraient survenir lors de l'exécution.
Quelles sont les prochaines étapes ?
À ce stade, TypeScript 5.3 est ce que Microsoft appelle "stable en termes de fonctionnalités". TypeScript 5.3 se concentrera sur les corrections de bogues, le polissage et certaines fonctionnalités d'édition à faible risque. Une version candidate sera disponible dans un peu plus d'un mois, suivie d'une version stable peu après.
Source : Microsoft
Et vous ?
Quel est votre avis sur le sujet ?
Quelles sont les fonctionnalités que vous aimeriez retrouver dans la prochaine version de Typescript ?
Que pensez-vous des fonctionnalités proposées par cette version de TypeScript ?
Voir aussi :
Microsoft annonce la Release Candidate de TypeScript 5.2 et présente une liste rapide des nouveautés de TypeScript 5.2
Microsoft annonce la sortie de la version bêta de TypeScript 5.0, et apporte un nouveau standard pour les décorateurs en plus de nombreuses autres améliorations