Dans ce chapitre, nous couvrirons certains types fréquents des valeurs communes dans du code JavaScript, et nous expliquerons les façons de représenter ces types en TypeScript. Ce n’est pas une liste exhaustive, et les futurs chapitres couvriront plus de manières de nommer et utiliser d’autres types.
Les types peuvent également apparaître d’autres endroits que des annotations. À mesure que vous apprenez à connaître les types, vous connaîtrez également les façons et endroits où l’on peut référer aux types pour former de nouvelles entités.
D’abord, passons en revue les types les plus basiques et communs, que vous rencontrerez probablement quand vous écrirez du code JavaScript ou TypeScript. Ces types formeront les blocs essentiels de types plus complexes.
Les primitives: string
, number
, et boolean
Le JavaScript possède trois primitives très communes : string
, number
, et boolean
.
Chacune d’entre elles a un type correspondant en TypeScript.
Comme vous vous y attendrez, ce sont les mêmes noms que vous verrez si vous utilisez l’opérateur typeof
sur les valeurs de ces types :
string
représente des chaînes de caractères comme"bonjour tout le monde"
number
correspond aux nombres comme42
. En JavaScript, tout est unnumber
- il n’existe aucun équivalent à unint
oufloat
. Tout est simplement unnumber
boolean
représente les deux valeurstrue
etfalse
Les noms de types
String
,Number
, etBoolean
(avec une première lettre majuscule) existent, mais réfèrent à des types spéciaux qui vont très rarement apparaître dans votre code. Utilisez toujoursstring
,number
, ouboolean
pour annoter vos types.
Tableaux
Pour préciser le type d’un tableau comme [1, 2, 3]
, vous pouvez utiliser la syntaxe number[]
; cette syntaxe peut être utilisée pour d’autres types (par exemple, string[]
est un tableau de chaînes de caractères, et ainsi de suite).
Vous pourriez aussi voir la notation Array<number>
, qui signifie la même chose.
Nous en apprendrons plus sur la notation T<U>
quand on couvrira les types génériques.
À noter que la notation
[number]
est différente; référez-vous à la section sur les Tuples.
any
TypeScript possède également un type spécial, any
, que vous pouvez utiliser dès que vous souhaitez qu’une valeur particulière ne cause pas d’erreurs à la vérification de types.
Quand une valeur est de type any
, vous pouvez accéder à toutes ses propriétés (qui seront, à leur tour, de type any
), l’appeler comme une fonction, l’assigner à (ou depuis) une valeur de tous types, ainsi que tout ce qui pourrait être légal :
tsTry
letobj : any = {x : 0 };// Aucune de ces lignes ne va émettre d'erreur.// Utiliser `any` désactive toute vérification de types, et TypeScript supposera// que vous connaissez l'environnement mieux que lui.obj .foo ();obj ();obj .bar = 100;obj = "hello";constn : number =obj ;
Le type any
est utile quand vous ne voulez pas écrire une très grande ligne de typage rien que pour convaincre TypeScript qu’une certaine ligne de code est valide.
noImplicitAny
Si vous ne précisez pas de type, et TypeScript ne peut pas l’inférer du contexte, le compilateur va adopter le type any
.
Vous voudrez peut-être l’éviter, cependant, parce qu’il n’y a aucune vérification de types sur any
.
Utilisez l’option noImplicitAny
pour relever toutes ces situations en tant qu’erreurs.
Annotations de Types sur des Variables
Quand vous déclarez une variable avec const
, var
, ou let
, vous pouvez optionnellement ajouter une annotation de type pour préciser explicitement le type de la variable :
tsTry
letmyName : string = "Alice";
TypeScript n’utilise pas de déclarations du style “types vers la gauche”, comme
int x = 0;
Les annotations de types iront toujours après la variable qui est typée.
Par contre, la plupart des cas, cela n’est pas nécessaire. Dès que possible, TypeScript essaiera d’inférer automatiquement les types de votre code. Par exemple, le type d’une variable est inféré en fonction du type de son initialiseur :
tsTry
// Pas d'annotation nécessaire -- inférer 'myName' montre que la variable est de type 'string'letmyName = "Alice";
La plupart du temps, vous n’aurez pas besoin d’apprendre les règles d’inférence. Si vous débutez avec TypeScript, essayez d’utiliser moins d’annotations que vous pensez nécessaire - vous verrez que TypeScript saura comprendre vos intentions bien plus souvent que vous ne le pensez.
Fonctions
Les fonctions sont les moyens principaux de transfert de données en JavaScript. TypeScript vous permet d’annoter précisément les types de données en entrée et en sortie de ces fonctions.
Annotations de Types de Paramètres
Quand vous déclarez une fonction, vous pouvez ajouter des annotations de types après chaque paramètre pour déclarer quel(s) type(s) la fonction accepte. Les annotations de types de paramètres iront après le nom des paramètres :
tsTry
// Annotation de type de paramètrefunctiongreet (name : string) {console .log ("Bonjour, " +name .toUpperCase () + " !!");}
Dès qu’un paramètre est annoté, les arguments de cette fonction seront vérifiés :
tsTry
// Ceci provoquera une erreur à l'exécutionArgument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.greet (42 );
Même si vous n’avez pas d’annotation sur vos paramètres, TypeScript vérifiera également que vous passez le nombre correct d’arguments lors de l’appel de la fonction.
Annotations de Type de Retour
Vous pouvez également ajouter des annotations de types de retour. Ces annotations apparaissent après les listes de paramètres :
tsTry
functiongetFavoriteNumber (): number {return 26;}
Tout comme les annotations de variables, vous n’avez généralement pas besoin d’en préciser tout le temps, parce que TypeScript inférera les types de retour d’une fonction en se basant sur les valeurs retournées.
Dans l’exemple ci-dessus, le : number
ne changera rien.
Certaines bases de code précisent explicitement le type de retour à des fins de documentation, pour éviter les changements accidentels, ou simplement par préférence personnelle.
Fonctions anonymes
Les fonctions anonymes sont légèrement différentes des déclarations de fonctions. Quand une fonction apparaît à un endroit où TypeScript peut déterminer comment elle sera appelée, les paramètres de cette fonction sont automatiquement typés.
Voici un exemple :
tsTry
// Pas d'annotations, mais TypeScript sera capable de repérer les bugsconstnames = ["Alice", "Bob", "Eve"];// Typage contextuel pour des fonctionsnames .forEach (function (s ) {Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?2551Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?console .log (s .()); toUppercase });// Le typage contextuel peut aussi s'appliquer aux fonctions fléchéesnames .forEach ((s ) => {Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?2551Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?console .log (s .()); toUppercase });
Même si s
n’a pas d’annotation de type, TypeScript a utilisé le type de la fonction forEach
, ainsi que le type inféré du tableau (qui est, donc, string[]
), pour déterminer le type de s
.
Ce procédé s’appelle typage contextuel car le contexte de cette fonction a permis de préciser quel type le paramètre doit avoir.
De la même façon que les règles de l’inférence, vous n’avez pas besoin d’apprendre exactement comment ça se passe, mais comprendre que cela peut se produire peut vous aider à remarquer les endroits où une annotation n’est pas nécessaire. Nous verrons plus tard des exemples où le contexte d’une variable peut lui changer son type.
Types Objets
À part les primitives, le type le plus commun que vous rencontrerez est le type objet. Il fait référence à toute valeur JavaScript qui peut avoir une propriété, c’est-à-dire quasiment toutes ! Pour définir un type objet, il suffit de lister ses propriétés et leurs types.
Par exemple, voici une fonction qui prend en paramètre un objet qui ressemble à un point à coordonnées :
tsTry
// L'annotation de type du paramètre est un objetfunctionprintCoord (pt : {x : number;y : number }) {console .log ("La valeur x de la coordonnée est " +pt .x );console .log ("La valeur y de la coordonnée est " +pt .y );}printCoord ({x : 3,y : 7 });
Ici, nous avons annoté un paramètre avec un type à deux propriétés - x
et y
- qui sont toutes les deux de type number
.
Vous pouvez utiliser ,
ou ;
pour séparer les propriétés, le dernier séparateur étant optionnel.
Il n’est également pas nécessaire de préciser le type d’une propriété.
Dans ce cas, TypeScript supposera que la propriété en question est de type any
.
Propriétés facultatives
Les types objet peuvent aussi préciser que certaines ou toutes leurs propriétés sont facultatives.
Pour ce faire, vous devrez ajouter un ?
après le nom de propriété :
tsTry
functionprintName (obj : {first : string;last ?: string }) {// ...}// Les deux sont OKprintName ({first : "Bob" });printName ({first : "Alice",last : "Alisson" });
En JavaScript, accéder à une propriété qui n’existe pas retourne undefined
au lieu d’une erreur.
De ce fait, quand vous lisez une propriété facultative, vous devrez vérifier qu’elle n’est pas undefined
avant de continuer :
tsTry
functionprintName (obj : {first : string;last ?: string }) {// Erreur - peut provoquer un crash si `obj.last` est undefined !'obj.last' is possibly 'undefined'.18048'obj.last' is possibly 'undefined'.console .log (obj .last .toUpperCase ());if (obj .last !==undefined ) {// OKconsole .log (obj .last .toUpperCase ());}// Une alternative plus sûre avec du JavaScript moderne :console .log (obj .last ?.toUpperCase ());}
Types Union
Le système de types de TypeScript permet de créer de nouveaux types en partant de types existants, à travers une grande variété opérateurs. Maintenant qu’on sait écrire des types, il est l’heure de les combiner de façons qui vont être intéressantes.
Définir un Type Union
La première façon de combiner des types est de créer un type union. Un type union est un type formé de deux ou plusieurs types, représentant des valeurs qui pourraient faire partie de n’importe lequel de ces types. Chacun des types de l’union est un membre de cette union.
Écrivons une fonction qui peut agir sur un number
ou sur un string
:
tsTry
functionprintId (id : number | string) {console .log ("Votre ID est : " +id );}// OKprintId (101);// OKprintId ("202");// ErreurArgument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.2345Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.printId ({myID : 22342 });
Utiliser les Types Union
Il est facile de fournir une valeur qui correspond à un type union - vous pouvez simplement fournir une valeur qui a un type membre de ce type union. Mais si vous avez une valeur dont le type est un type union, que faire ?
TypeScript va permettre une opération uniquement si elle est valide pour tous les membres de l’union.
Par exemple, si vous avez le type string | number
, vous ne pouvez pas utiliser les méthodes qui sont disponibles uniquement dans le type string
:
tsTry
functionprintId (id : number | string) {Property 'toUpperCase' does not exist on type 'string | number'. Property 'toUpperCase' does not exist on type 'number'.2339Property 'toUpperCase' does not exist on type 'string | number'. Property 'toUpperCase' does not exist on type 'number'.console .log (id .()); toUpperCase }
La solution est de rétrécir l’union avec du code, de la même façon qu’avec du code JavaScript sans annotation de types. Le rétrécissement se produit quand TypeScript peut déduire un type plus spécifique pour une certaine valeur, en se basant sur la structure du code.
Par exemple, TypeScript sait que si typeof
une valeur renvoie string
, cette valeur peut uniquement être un string
:
tsTry
functionprintId (id : number | string) {if (typeofid === "string") {// Dans cette branche, id est un stringconsole .log (id .toUpperCase ());} else {// Ici, id est un nombreconsole .log (id );}}
Un autre exemple qui implique d’utiliser Array.isArray
:
tsTry
functionwelcomePeople (x : string[] | string) {if (Array .isArray (x )) {// Ici, 'x' est un 'string[]'console .log ("Bonjour, " +x .join (" et "));} else {// Ici, 'x' est un 'string'console .log ("Bienvenue, voyageur solitaire " +x );}}
Remarquez que dans la branche else
, nous n’avons pas eu à faire quoi que ce soit - si x
n’est pas un string[]
, alors il doit être un string
.
Parfois, vous aurez des unions où les types membres ont des éléments en commun.
Par exemple, les tableaux et les string
possèdent la méthode slice
.
Si chaque membre de l’union a cette propriété, vous pourrez vous en servir sans faire de rétrécissement :
tsTry
// Le type de retour est number[] | stringfunctiongetFirstThree (x : number[] | string) {returnx .slice (0, 3);}
L’union de types paraît posséder l’intersection des propriétés de ces types, ce qui peut paraître perturbant. C’est voulu : le nom union vient de la théorie des ensembles. L’union
number | string
est créée en obtenant l’union des valeurs de chaque type. Remarquez que pour deux ensembles avec des éléments qui décrivent chaque ensemble, seule l’intersection de ces éléments s’applique à l’union de ces ensembles. Par exemple, si on a une salle remplie de grandes personnes avec un chapeau, avec des personnes parlant l’espagnol et portant un chapeau, la seule description commune qui s’applique à l’union de ces personnes (à toutes ces personnes) est le fait qu’elles portent toutes un chapeau.
Alias de Types
Jusque-là, vous avez utilisé les types objet et types union en les écrivant directement dans les annotations de types. C’est convenable, mais vous voudrez souvent utiliser le même type plus d’une fois, et y référer avec un seul nom.
Un alias de type est exactement cela - un nom pour un type. Voici la syntaxe d’un alias de type :
tsTry
typePoint = {x : number;y : number;};// Identique à l'exemple précédentfunctionprintCoord (pt :Point ) {console .log ("La valeur de la coordonnée x est " +pt .x );console .log ("La valeur de la coordonnée y est " +pt .y );}printCoord ({x : 100,y : 100 });
Vous pouvez même utiliser les alias de types pour nommer toutes sortes de types, pas juste des types objet. Par exemple, un alias de type peut nommer un type union :
tsTry
typeID = number | string;
Remarquez que les alias sont uniquement des alias - vous ne pouvez pas utiliser d’alias pour créer des variantes / versions différentes d’un type déjà existant. En utilisant le type alias, c’est comme si vous aviez écrit le type remplacé par l’alias. En d’autres termes, ce code peut paraître illégal, mais TypeScript l’accepte parce que les deux types sont, en réalité, deux alias pour le même type :
tsTry
typeUserInputSanitizedString = string;functionsanitizeInput (str : string):UserInputSanitizedString {returnsanitize (str );}// Aseptiser l'entrée reçueletuserInput =sanitizeInput (getInput ());// Peut toujours recevoir un stringuserInput = "new input";
Interfaces
Une déclaration d’interface est une autre façon de nommer un type objet :
tsTry
interfacePoint {x : number;y : number;}functionprintCoord (pt :Point ) {console .log ("La valeur de la coordonnée x est " +pt .x );console .log ("La valeur de la coordonnée y est " +pt .y );}printCoord ({x : 100,y : 100 });
Tout comme les alias de types ci-dessus, l’exemple des interfaces fonctionne de la même façon qu’avec une annotation anonyme de propriétés.
TypeScript vérifie uniquement la structure de la valeur transmise à printCoord
- l’appel est valide du moment que l’objet possède les propriétés requises.
Le fait de n’être concerné que par la structure et capacités des types permet de dire que TypeScript est un système typé structurellement.
Différence entre les alias de types et interfaces
Les alias de types et interfaces sont très similaires, et interchangeables la plupart des cas.
La quasi-totalité des fonctionnalités d’une interface
sont disponibles dans les type
. La différence principale est le fait qu’un type ne peut pas être modifié pour y ajouter des propriétés, tandis qu’une interface est toujours extensible.
Interface |
Type |
---|---|
Étendre une interface
|
Étendre un type avec des intersections
|
Ajouter de nouvelles propriétés dans une interface existante
|
Un type ne peut plus être changé une fois créé
|
Vous en apprendrez plus sur ces concepts dans les chapitres suivants, donc ne vous inquiétez pas si vous ne comprenez pas l’erreur immédiatement.
- Avant la version 4.2 de TypeScript, les alias de types pourraient apparaître dans les messages d’erreurs, sometimes in place of the equivalent anonymous type (which may or may not be desirable). Interfaces will always be named in error messages.
- Les alias de types ne sont pas concernés par les fusions de déclarations, au contraire des interfaces.
- Les interfaces ne servent qu’à déclarer les formes d’objets, et ne peuvent pas renommer des primitives.
- Les interfaces apparaissent toujours dans leurs formes originelles dans les messages d’erreur, mais seulement si elles sont utilisées avec leurs noms.
La plupart du temps, vous êtes libres d’utiliser un type ou une interface, et TypeScript vous dira si vous avez besoin de l’autre déclaration. En règle générale, utilisez une interface
sauf si vous avez besoin d’utiliser des type
.
Assertions de Types
Parfois, vous aurez des informations sur le type d’une valeur que TypeScript ne connaît pas.
Par exemple, si vous appelez document.getElementById
, TypeScript saura uniquement que c’est une espèce d’HTMLElement
, mais vous savez peut-être que cet appel renverra un HTMLCanvasElement
avec un certain ID.
Dans cette situation, vous pourrez utiliser une assertion de types pour spécifier un type plus précis :
tsTry
constmyCanvas =document .getElementById ("main_canvas") asHTMLCanvasElement ;
Tout comme les annotations, les assertions de types sont enlevées par le compilateur et n’affecteront pas l’exécution de votre code.
Une écriture équivalente consiste à utiliser les chevrons (sauf si votre fichier a l’extension .tsx
) :
tsTry
constmyCanvas = <HTMLCanvasElement >document .getElementById ("main_canvas");
Rappel : Les assertions de types sont retirées à la compilation, et il n’existe aucune vérification associée à ces assertions. Si l’assertion est fausse, il n’y aura ni erreur ni
null
qui seront renvoyés.
TypeScript permet de faire des assertions qui sont plus spécifiques ou moins spécifiques que le type d’origine. Cette règle interdit les assertions impossibles, tel que :
tsTry
constConversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.2352Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.x = "bonjour" as number;
Cette règle peut parfois être trop restrictive, et pourrait interdire des conversions plus complexes mais qui restent valides.
Dans cette situation, vous pourrez faire une première conversion vers any
(ou unknown
, que nous introduirons plus tard), puis vers le type désiré :
tsTry
consta = (expr as any) asT ;
Types littéraux
En plus des types généraux comme string
ou number
, nous pouvons faire des références à des string
ou number
plus spécifiques dans les annotations de types.
Une façon de comprendre ce point est de considérer les différentes façons dont JavaScript déclare ses variables. var
et let
permettent de changer ce que contient la variable, au contraire de const
. Ces comportements sont reflétés dans la manière avec laquelle TypeScript déduit les types.
tsTry
letchangingString = "Hello World";changingString = "Olá Mundo";// `changingString` peut représenter n'importe quel string, donc// TypeScript dit que cette variable est de type stringchangingString ;constconstantString = "Bonjour tout le monde";// `constantString` ne peut représenter qu'un seul string, donc TypeScript// lui assigne un type littéralconstantString ;
Les types littéraux ne sont pas très utiles tous seuls :
tsTry
letx : "bonjour" = "bonjour";// OKx = "bonjour";// ...Type '"salut"' is not assignable to type '"bonjour"'.2322Type '"salut"' is not assignable to type '"bonjour"'.= "salut"; x
Une variable qui n’a qu’une seule valeur n’est pas très utile !
Mais en combinant les types littéraux dans des unions, vous pouvez exprimer des concepts bien plus utiles - par exemple, il est possible de créer des fonctions qui n’acceptent que certaines valeurs précises :
tsTry
functionprintText (s : string,alignment : "left" | "right" | "center") {// ...}printText ("Bonjour tout le monde", "left");Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.2345Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.printText ("Yo mec","centre" );
Les types littéraux numériques fonctionnent de la même manière :
tsTry
functioncompare (a : string,b : string): -1 | 0 | 1 {returna ===b ? 0 :a >b ? 1 : -1;}
Bien sûr, il est possible de combiner des primitives avec des types objet :
tsTry
interfaceOptions {width : number;}functionconfigure (x :Options | "auto") {// ...}configure ({width : 100 });configure ("auto");Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.2345Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.configure ("automatic" );
Un autre type littéral existe : les littéraux booléens.
Il n’existe que deux types booléens littéraux, et comme vous pourriez le deviner, ce sont true
et false
.
Le type boolean
, est, en réalité, un type alias de l’union true | false
.
Inférence littérale
Quand vous créez une variable qui est un objet, TypeScript pense que les propriétés de cet objet pourraient changer de valeur. Par exemple, si vous écrivez ce code :
tsTry
constobj = {counter : 0 };if (someCondition ) {obj .counter = 1;}
TypeScript ne pense pas qu’assigner 1
à un champ qui avait 0
est une erreur.
En d’autres termes obj.counter
est de type number
, pas 0
, parce que les types sont utilisés pour déterminer le comportement à la lecture et l’écriture.
Même chose pour les string
:
tsTry
constreq = {url : "https://example.com",method : "GET" };Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.2345Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.handleRequest (req .url ,req .method );
Dans l’exemple ci-dessus, req.method
est inféré comme étant un string
, pas "GET"
. BIl se peut qu’il y ait du code entre la déclaration de req
et l’appel de handleRequest
, et ce code pourrait assigner un nouveau string
comme "GUESS"
to req.method
. Donc TypeScript considère que ce code contient une erreur.
Il y a deux façons de corriger ce problème.
-
Vous pouvez ajouter une assertion à deux endroits :
ts
Try// 1er endroit :constreq = {url : "https://example.com",method : "GET" as "GET" };// 2ème endroithandleRequest (req .url ,req .method as "GET");Le premier changement signifie “Je veux que
req.method
ait toujours le type littéral"GET"
”, empêchant tout changement de cette valeur vers"GUESS"
plus tard. Le deuxième changement signifie “Je sais que, pour certaines raisons,req.method
est égal à"GET"
“. -
Vous pouvez utiliser
as const
pour convertir l’objet entier en types littéraux :ts
Tryconstreq = {url : "https://example.com",method : "GET" } asconst ;handleRequest (req .url ,req .method );
Le suffixe as const
vaut la même chose que const
mais pour le système de types, garantissant que toutes les propriétés aient un type littéral, au lieu d’un type plus général comme string
ou number
.
null
et undefined
JavaScript a deux valeurs primitives pour signaler une valeur inexistante ou non-initialisée : null
et undefined
.
TypeScript a deux types des mêmes noms. Le comportement de ces types dépend de l’activation de l’option strictNullChecks
.
strictNullChecks
désactivé
Si strictNullChecks
est désactivé, les valeurs qui pourraient être null
ou undefined
peuvent toujours être lues, et les valeurs null
et undefined
peuvent être assignées à des variables de tous types.
Ce comportement est similaire aux langages qui n’ont pas de vérification pour null
ou undefined
(ex. Java ou C#).
Ne pas vérifier pour ces deux valeurs tend à être une source importante de bugs ; nous recommandons toujours d’activer strictNullChecks
s’il est pratique de le faire.
strictNullChecks
activé
Si strictNullChecks
est activé, quand une valeur est null
ou undefined
, vous devrez vous assurer que ces deux types sont écartés avant d’utiliser des méthodes ou des propriétés sous ces valeurs.
Tout comme undefined
doit être éliminé avant d’utiliser une propriété facultative, vous pouvez vous servir du rétrécissement pour éliminer les valeurs qui pourraient être null
:
tsTry
functiondoSomething (x : string | null) {if (x === null) {// ne rien faire} else {console .log ("Bonjour, " +x .toUpperCase ());}}
Opérateur d’assertion non-nulle (Suffixe !
)
TypeScript possède une syntaxe spéciale pour éliminer null
et undefined
d’un type sans passer par un rétrécissement.
Écrire !
après toute expression est effectivement une assertion que cette valeur n’est ni null
, ni undefined
:
tsTry
functionliveDangerously (x ?: number | null) {// Pas d'erreurconsole .log (x !.toFixed ());}
Tout comme les autres assertions, votre code ne sera pas changé à l’exécution, donc n’utilisez l’opérateur !
que si vous savez que votre type ne peut jamais être null
ni undefined
.
Enums
Les Enums sont une fonctionnalité ajoutée à JavaScript par TypeScript. Elle permet de décrire une valeur qui pourrait faire partie d’un ensemble de constantes nommées. Au contraire de la plupart des fonctionnalités TypeScript, elle n’est pas un ajout au niveau du système de types, mais bel et bien un ajout qui sera reflété à l’exécution. De ce fait, vous devriez savoir que cette possibilité existe, mais vous ne devriez vous en servir que si vous en avez la certitude. Vous pouvez lire plus dans la page de référence d’Enums.
Primitives moins fréquentes
Il serait intéressant de mentionner le reste des primitives JavaScript représentées dans le système de types, bien que nous ne rentrerons pas dans leurs détails.
bigint
À partir d’ES2020, il existe une primitive JavaScript pour les très grands entiers, BigInt
:
tsTry
// Création d'un BigInt via la fonctionconstoneHundred : bigint =BigInt (100);// Création d'un BigInt via la syntaxe littéraleconstanotherHundred : bigint = 100n;
Vous pouvez en apprendre plus sur les BigInt dans les notes de changement de TypeScript 3.2.
symbol
Il existe une primitive en JavaScript qui sert à créer des références uniques via la fonction Symbol()
:
tsTry
constfirstName =Symbol ("nom");constsecondName =Symbol ("nom");if (This comparison appears to be unintentional because the types 'typeof firstName' and 'typeof secondName' have no overlap.2367This comparison appears to be unintentional because the types 'typeof firstName' and 'typeof secondName' have no overlap.firstName ===secondName ) {// Ne peut jamais se produire}
Vous pouvez en savoir plus dans la page de référence des Symbols.