Developpez.com

Le Club des Développeurs et IT Pro

L'équipe TypeScript indique que la version 2.1 est disponible

Et apporte le support de async/await pour ES5/ES3 ainsi que les extensions d'objets

Le 2016-12-08 12:44:20, par Stéphane le calme, Chroniqueur Actualités
Conformément à son calendrier, Microsoft a rendu disponible la version 2.1 de TypeScript. Voici quelques nouveautés.

Fonctions asynchrones :

Cette version de TypeScript apporte les fonctions asynchrones de bas niveau. Les développeurs seront désormais capable d’utiliser async/await et cibler ES3/ES5 sans avoir à utiliser des outils supplémentaires.

Les restes et les extensions d’objets :

Ces objets font partie d’une nouvelle proposition pour ES2017 (ECMA Script 2017) visant à faciliter la copie, la fusion et la séparation partielles des objets. La fonctionnalité est déjà appelée lors de l'utilisation de bibliothèques comme Redux.

Avec les extensions d'objet, la création d'une copie superficielle d'un objet a grandement été simplifiée :

Code TypeScript :
1
2
3
4
5
6
7
let copy = { ...original }; 
  
  
De même, il est possible de fusionner différents objets. Dans cet exemple, nous avons des propriétés de foo, bar et baz.  
  
  
let merged = { ...foo, ...bar, ...baz };

Il est même possible d’ajouter de nouvelles propriétés durant le processus :

Code TypeScript :
1
2
3
4
5
6
let nowYoureHavingTooMuchFun = { 
    hello: 100, 
    ...foo, 
    world: 200, 
    ...bar, 
}

Microsoft recommande de garder à l’esprit que lorsque vous utilisez les opérateurs d’extensions d’objets, toutes propriétés dans les extensions ultérieures l’emportent sur les propriétés créées précédemment. Ainsi, dans le dernier exemple, si bar avait une propriété nommée world, alors bar.world aurait été utilisé à la place de ce qui a été écrit.

Les restes d'objet sont complémentaires aux extensions d’objets dans la mesure où ils peuvent extraire toutes les propriétés supplémentaires qui ne sont pas obtenues en déstructurant un élément :

Code TypeScript :
let { a, b, c, ...defghijklmnopqrstuvwxyz } = alphabet;


Les types keyof et Lookup

Nombreuses sont les bibliothèques qui tirent profit du fait que les objets sont (pour la plupart) une collection de valeurs. Étant donné que TypeScript connaît les propriétés de chaque valeur, il existe un ensemble de chaînes de caractères connues (ou clés) que vous pouvez utiliser pour les recherches. C’est ici qu’intervient l’opérateur keyof :

Code TypeScript :
1
2
3
4
5
6
7
interface Person { 
    name: string; 
    age: number; 
    location: string; 
} 
  
let propName: keyof Person;

Cet exemple est équivalent à celui-ci

Code TypeScript :
let propName: "name" | "age" | "location";

Cet opérateur keyof est en réalité une requête de type d’index ; comme une requête pour des clés sur des types d'objet, de la même façon que typeof pourrait être utilisé comme une requête pour pour des types sur des valeurs.

Les types d’accès indexés, également appelés types lookup, ressemblent dans leur syntaxe à un accès à un élément, mais sont écrits comme des types :

Code TypeScript :
1
2
3
4
5
6
7
interface Person { 
    name: string; 
    age: number; 
    location: string; 
} 
  
let a: Person["age"];

Cela revient à dire que "a" obtient le type de la propriété age dans Person. En d'autres termes:

Code TypeScript :
let a: number;

Lors de l'indexation avec une union de types littoraux, l'opérateur recherche chaque propriété et regroupe les types respectifs.

Code TypeScript :
1
2
// Equivalent to the type 'string | number' 
let nameOrAge: Person["name" | "age"];

Ce modèle peut être utilisé avec d'autres parties du système de type pour obtenir des recherches de type sécurisé, servant les utilisateurs de bibliothèques comme Ember.

Code TypeScript :
1
2
3
4
5
6
7
8
9
10
function get<T, K extends keyof T>(obj: T, propertyName: K): T[K] { 
    return obj[propertyName]; 
} 
  
let x = { foo: 10, bar: "hello!" }; 
  
let foo = get(x, "foo"); // has type 'number' 
let bar = get(x, "bar"); // has type 'string' 
  
let oops = get(x, "wargarbl"); // error!

Les types mappés

Disons que nous avons un type Person

Code TypeScript :
1
2
3
4
5
interface Person { 
    name: string; 
    age: number; 
    location: string; 
}

La plupart du temps, nous voulons prendre un type existant et rendre chacune de ses propriétés entièrement facultative. Avec Person, nous pourrions écrire ce qui suit:

Code TypeScript :
1
2
3
4
5
interface PartialPerson { 
    name?: string; 
    age?: number; 
    location?: string; 
}

Remarquez que nous devions définir un type complètement nouveau.

De même, nous pourrions vouloir créer un type apparenté à Person où toutes les propriétés sont booléennes

Code TypeScript :
1
2
3
4
5
interface BooleanifiedPerson { 
    name: boolean; 
    age: boolean; 
    location: boolean; 
}

Ou avec des propriétés en lecture seule

Code TypeScript :
1
2
3
4
5
interface FrozenPerson { 
    readonly name: string; 
    readonly age: number; 
    readonly location: string; 
}

Remarquez toute cette répétition alors que, dans l’idéal, une grande partie de la même information dans chaque variante de Person aurait pu être partagée.

Voici comment nous pouvons écrire BooleanifiedPerson avec un type mappé.

Code TypeScript :
1
2
3
type BooleanifiedPerson = { 
    [P in "name" | "age" | "location"]: boolean 
};

Les types mappés sont obtenus suite à une union de types littoraux et en calculant un ensemble de propriétés pour un nouveau type d'objet. Ils sont comme des listes de compréhension en Python, mais au lieu de produire de nouveaux éléments dans une liste, ils produisent de nouvelles propriétés dans un type.

Il est possible d’utiliser l’opérateur keyof pour réduire le code

Code TypeScript :
1
2
3
type BooleanifiedPerson = { 
    [P in keyof Person]: boolean 
};

et le généraliser par la suite

Code TypeScript :
1
2
3
4
5
type Booleanify<T> = { 
    [P in keyof T]: boolean 
}; 
  
type BooleanifiedPerson = Booleanify<Person>;

Avec les types mappés, nous n'avons plus besoin de créer de nouvelles variantes partielles ou en lecture seule des types existants.

Code TypeScript :
1
2
3
4
5
6
7
8
9
// Keep types the same, but make every property optional. 
type Partial<T> = { 
    [P in keyof T]?: T[P]; 
}; 
  
// Keep types the same, but make each property to be read-only. 
type Readonly<T> = { 
    readonly [P in keyof T]: T[P]; 
};

Source : blog MSDN
  Discussion forum
3 commentaires