Qu'est-ce que le Narrowing dans TypeScript
Le narrowing sert à afiner (rendre plus précis) un type, ce qui est souvent pratique dans le cas d'une union de types.
Typeof type guards
En JS il y existe l'opérateur typeof
, il est également disponible avec TypeScript et voici la liste des valeurs que TypeScript reconnait :
typeof x == "string";
typeof x == "number";
typeof x == "bigint";
typeof x == "boolean";
typeof x == "symbol";
typeof x == "undefined";
typeof x == "object";
typeof x == "function";
Ça peut être utile de connaitre ces valeurs pour faire du narrowing.
Exemples
Fonction recevant une union simple
Créons une fonction btcToUsd
qui permet de convertir des BTC en $, elle accepte soit un nombre soit un objet en paramètre.
On peut faire du narrowing en testant le type de l'argument :
type Account = {
address: string,
btc: number
}
function btcToUsd(btc: number | Account): number {
if(typeof btc === 'object') {
return btc.btc * 22000;
}
return btc * 22000;
}
btcToUsd(0.15);
btcToUsd({address: 'bc1xxx', btc: 0.2});
On vient d'aider TypeScript à determiner le type de l'argument : à l'intérieur de la condition on sait que le type est forcément un Acount et non pas un nombre.
On aurait aussi pu faire l'inverse (tester si c'est un nombre).
Fonction recevant plusieurs objets ou type similaires
Le cas précédent était plutôt simple, cependant il y a des situations où la fonction peut reçevoir une union d'objets différents ou types ayant des propriétés communes.
Comme TypeScript ne permet pas d'utiliser typeof
sur de tels types directement, voici comment faire :
type BtcAccount = {
address: string,
btc: number
}
type EthAccount = {
address: string,
eth: number
}
type AvaxAccount = {
address: string,
avax: number
}
function getBalance(acc: BtcAccount | EthAccount | AvaxAccount): number {
if('btc' in acc) {
return acc.btc;
} else if('eth' in acc) {
return acc.eth;
} else if('avax' in acc) {
return acc.avax;
} else {
throw new Error('Invalid account');
}
}
Comme on ne pouvait pas utiliser typeof acc == BtcAccount
directement par exemple, on peut faire du narrowing en testant qu'un objet a une propriété spécifique.
Conclusion
Il existe de nombreuses situations différentes et nous n'allons pas toutes les traiter mais ça devrait déjà vous aider si jamais vous avez à faire du narrowing.