Microsoft a annoncé la disponibilité de TypeScript 2.8.Types conditionnels
Les types conditionnels sont une nouvelle construction dans TypeScript qui permette de choisir des types basés sur d'autres types. Ils prennent la forme
| Code TypeScript : | Sélectionner tout |
A extends B ? C : D
Prenons un exemple spécifique:
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | interface Animal { live(): void; } interface Dog extends Animal { woof(): void; } // Has type 'number' type Foo = Dog extends Animal ? number : string; // Has type 'string' type Bar = RegExp extends Dog ? number : string; |
Par exemple, prenons la fonction suivante :
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 | interface Id { id: number, /* other fields */ } interface Name { name: string, /* other fields */ } declare function createLabel(id: number): Id; declare function createLabel(name: string): Name; declare function createLabel(name: string | number): Id | Name; |
- Si une bibliothèque doit faire le même type de choix encore et encore tout au long de son API, cela devient fastidieux ;
- Nous devons créer trois surcharges : une pour chaque cas lorsque nous sommes sûrs du type, et une pour le cas le plus général. Pour tous les autres cas que nous aurions à traiter, le nombre de surcharges augmenterait de façon exponentielle.
Au lieu de cela, nous pouvons utiliser un type conditionnel pour réduire à la fois nos surcharges et créer un alias de type afin que nous puissions réutiliser cette logique.
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | type IdOrName<T extends number | string> = T extends number ? Id : Name; declare function createLabel<T extends number | string>(idOrName: T): T extends number ? Id : Name; let a = createLabel("typescript"); // Name let b = createLabel(2.8); // Id let c = createLabel("" as any); // Id | Name let d = createLabel("" as never); // never |
Distribution sur les unions avec les types conditionnels
Lorsque les types conditionnels agissent sur un seul paramètre de type, ils se répartissent entre les unions. Donc, dans l'exemple suivant, Bar a le type string [] | number [] car Foo[/CB] est appliqué à l’union type [C]string | number
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | type Foo<T> = T extends any ? T[] : never; /** * Foo distributes on 'string | number' to the type * * (string extends any ? string[] : never) | * (number extends any ? number[] : never) * * which boils down to * * string[] | number[] */ type Bar = Foo<string | number>; |
| Code TypeScript : | Sélectionner tout |
1 2 3 4 | type Foo<T> = [T] extends [any] ? T[] : never; // Boils down to Array<string | number> type Bar = Foo<string | number>;; |

Contrôle granulaire sur les modificateurs de type mappés
Les types d'objets mappés de TypeScript sont une construction incroyablement puissante. Une fonctionnalité pratique est qu'ils permettent aux utilisateurs de créer de nouveaux types avec des modificateurs définis pour toutes leurs propriétés. Par exemple, le type suivant crée un nouveau type basé sur T et où chaque propriété dans T devient readonly et optionnel (?).
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 | // Creates a type with all the properties in T, // but marked both readonly and optional. type ReadonlyAndPartial<T> = { readonly [P in keyof T]?: T[P] } |
TypeScript 2.8 fournit une nouvelle syntaxe pour supprimer les modificateurs dans les types mappés avec l'opérateur -, et une nouvelle syntaxe plus explicite pour ajouter des modificateurs avec l'opérateur +. Par exemple :
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | type Mutable<T> = { -readonly [P in keyof T]: T[P] } interface Foo { readonly abc: number; def?: string; } // 'abc' is no longer read-only, but 'def' is still optional. type TotallyMutableFoo = Mutable<Foo> |
De même, TypeScript fournit maintenant un nouveau type requis dans lib.d.ts qui supprime l'optionalité de chaque propriété :
| Code TypeScript : | Sélectionner tout |
1 2 3 4 5 6 | /** * Make all properties in T required */ type Required<T> = { [P in keyof T]-?: T[P]; } |
| Code TypeScript : | Sélectionner tout |
1 2 3 | type ReadonlyAndPartial<T> = { +readonly [P in keyof T]+?: T[P]; } |
Et vous ?
Quels sont les changements qui vous intéressent le plus ?
Vous avez lu gratuitement 3 269 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.