L'opérateur satisfies : le meilleur des deux mondes
Beaucoup de développeurs annotent encore leurs objets de configuration avec un type explicite, au prix d'une perte d'inférence précise. L'opérateur satisfies, disponible depuis TypeScript 4.9, vérifie la conformité d'une valeur à un type sans élargir son type inféré.
type Couleur = "red" | "green" | "blue";
const palette = {
primaire: "red",
secondaire: "blue"
} satisfies Record<string, Couleur>;
// palette.primaire est inféré comme "red", pas comme Couleur
palette.primaire.toUpperCase();
Avec une annotation classique (: Record<string, Couleur>), TypeScript aurait élargi chaque propriété au type Couleur, perdant l'information que primaire vaut précisément "red". satisfies conserve cette précision tout en garantissant l'erreur si une valeur ne respecte pas la contrainte.
Unions discriminées et narrowing exhaustif
Les unions discriminées restent la façon la plus robuste de modéliser des états mutuellement exclusifs. Combinées à une fonction utilitaire assertNever, elles rendent le compilateur capable de détecter les cas oubliés.
type Etat =
| { statut: "chargement" }
| { statut: "succes"; donnees: string[] }
| { statut: "erreur"; message: string };
function assertNever(x: never): never {
throw new Error("Cas non gere: " + JSON.stringify(x));
}
function afficher(e: Etat): string {
switch (e.statut) {
case "chargement": return "...";
case "succes": return e.donnees.join(", ");
case "erreur": return e.message;
default: return assertNever(e);
}
}
Si un nouveau statut est ajouté à l'union sans être traité dans le switch, la branche default ne compile plus : l'erreur remonte immédiatement, avant même l'exécution.
Types littéraux de gabarit (template literal types)
Les template literal types permettent de construire des types chaînes à partir de motifs, utiles pour typer des routes, des noms d'événements ou des variables CSS.
type Ressource = "user" | "post" | "comment";
type Route = `/api/${Ressource}/${number}`;
const r: Route = "/api/post/42"; // valide
Points de vigilance
- satisfies ne remplace pas les annotations de fonctions publiques : il est surtout pertinent pour les valeurs littérales internes.
- Préférez
constassertions (as const) en complément desatisfiesquand vous voulez aussi figer les tableaux et littéraux en lecture seule. - L'exhaustivité via
neverne fonctionne que si le compilateur peut réellement réduire l'union à zéro membre : évitez lesanyqui cassent la chaîne d'inférence.