as const en TypeScript transforme les valeurs et les propriétés d'un objet/tableau en types littéraux et en readonly. Cela permet une typage stricte : les valeurs ne "s'étendent" pas au type de base, mais conservent leur valeur spécifique.
Exemple :
const a = { status: 'success' }; // Type : { status: string } const b = { status: 'success' } as const; // Type : { readonly status: "success" }
Avantages :
Inconvénients/Particularités :
Question : Que se passe-t-il si vous utilisez as const pour un tableau de chaînes, quel sera son type, et pourra-t-il être transmis comme un tableau de chaînes habituel string[] ?
Réponse : Le type sera readonly ["a", "b", "c"], c'est-à-dire un tuple de types littéraux avec une contrainte readonly. Ce tableau est incompatible avec le type string[]; il ne peut pas être transmis directement là où un tableau de chaînes modifiable est attendu.
const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // Erreur ! Type incompatible
Histoire
Projet : Un tableau d'actionTypes a été conservé comme un tableau constant avec as const, puis on a essayé de le transmettre à une fonction attendue de type string[]. On a rencontré une erreur de type, il a fallu le convertir explicitement à l'aide de
.slice()ou[...arr].
Histoire
Projet : Dans un micro-framework Redux, le type action.type a été défini comme un littéral via as const. Lors de la mise en œuvre d'un switch-case, on a oublié le typage strict, ne traitant pas tous les littéraux possibles, ce qui a fait échouer le contrôle exhaustif — l'erreur n'est pas apparue tant qu'on n'a pas ajouté une nouvelle action.
Histoire
Projet : Lors de l'auto-génération d'endpoints API, on a décrit leurs clés à l'aide d'un tableau as const. Tenter d'utiliser ces clés comme index d'un Record<string, ...> a échoué en raison de l'incompatibilité des types — il a fallu ajouter une conversion, ou utiliser explicitement les types des clés du tableau.