Menu

as en TypeScript : assertions de type et « cast » expliqués

Le mot-clé as demande à TypeScript de traiter une valeur comme un autre type. Ce n'est pas un cast : rien n'est converti ni vérifié à l'exécution. Découvrez la syntaxe as et celle à chevrons, ce qu'autorise le compilateur, les doubles assertions via unknown, et quand un type guard est le meilleur outil.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

value as Type est une assertion de type : elle demande à TypeScript de traiter value comme un Type. On parle souvent de cast, mais ce n'est qu'une instruction donnée au compilateur. Elle est effacée de la sortie JavaScript, ne convertit rien et ne vérifie rien à l'exécution.

C'est l'usage typique : vous en savez plus sur une valeur que le compilateur (ici, la forme d'un JSON), et vous le lui dites. Si vous vous trompez, rien ne vous avertit. Les sections suivantes montrent ce que cela implique et quand une vérification à l'exécution est un meilleur choix.

as et la syntaxe à chevrons

La même assertion s'écrit de deux façons :

const someValue: unknown = "hello";
const a = someValue as string;   // as syntax
const b = <string>someValue;     // angle-bracket syntax, same meaning

La forme à chevrons n'est pas autorisée dans les fichiers .tsx, où <string> se lirait comme une balise JSX. Utilisez as partout et la question ne se pose jamais. Les assertions ont une priorité faible : entourez-les de parenthèses quand l'expression continue, (value as string).length.

Les assertions ne convertissent pas les valeurs

C'est ce point qui cause de vrais bugs. Une assertion change ce que le compilateur croit d'une valeur, pas la valeur elle-même :

Le compilateur croit que asserted est un number, donc asserted + 1 passe la vérification comme une opération arithmétique. À l'exécution, c'est toujours la chaîne "42", et JavaScript concatène. Pour changer le type d'une valeur, convertissez-la : Number(x), String(x), Boolean(x), BigInt(x), new Date(x). La page convertir une chaîne en nombre compare les fonctions de conversion.

Vous voulezÉcrivezEffet à l'exécution
Indiquer au compilateur un type que vous connaissezx as Taucun
Transformer une chaîne en nombreNumber(x), parseInt(x, 10)convertit
Transformer n'importe quoi en chaîneString(x), `${x}`convertit
Vérifier d'abord le typeun type guard, typeof, instanceofvérifie

Ce qu'autorise le compilateur

as n'est pas illimité. TypeScript autorise x as T quand l'un des types est assignable à l'autre : élargir ("a" as string, dog as Animal) comme affiner (animal as Dog, unknown as User) est accepté. Quand les types ne se recouvrent pas du tout, il refuse :

Le compilateur signale index.ts(3,11): error TS2352: Conversion 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. Le message nomme lui-même l'échappatoire : input as unknown as number. Cette double assertion compile, et elle est exactement aussi fausse à l'exécution que l'exemple précédent. Quand vous en ressentez le besoin, la bonne correction est en général une conversion (Number(input)) ou un autre type.

La règle de recouvrement est souple pour les objets. Un littéral objet qui possède une partie des propriétés est accepté, et c'est ainsi que as laisse discrètement passer des objets incomplets :

Une annotation (const draft: User = { name: "Ada" }) ou satisfies User signalerait l'email manquant (TS2741). N'utilisez as sur un littéral objet que si vous comptez vraiment le compléter plus tard, et préférez construire l'objet complet.

as const, c'est autre chose

as const ressemble à une assertion mais fait l'inverse d'un assouplissement : il rend un littéral aussi étroit que possible. Les chaînes restent des types littéraux, les tableaux deviennent des tuples readonly et les propriétés d'objet deviennent readonly.

C'est sûr, car cela décrit exactement le littéral au lieu d'affirmer quelque chose que le compilateur ne peut pas voir. (Le sizes as readonly string[] dans isSize est une assertion d'élargissement, sûre elle aussi : elle permet à includes d'accepter n'importe quelle chaîne.) Voir types littéraux pour en savoir plus.

Quand un type guard est le meilleur outil

as est une affirmation ; un type guard est une vérification. À une frontière où les données viennent de l'extérieur de votre code (JSON, fetch, localStorage, saisie utilisateur, message), l'affirmation peut être fausse, et une assertion transforme une erreur claire à la frontière en une erreur déroutante ailleurs.

Un guide sommaire des outils qui se ressemblent :

OutilVérifie à la compilationVérifie à l'exécutionÀ utiliser quand
Annotation const x: T = ...oui, entièrementnonvous construisez la valeur vous-même
satisfies Toui, entièrement, garde le type inférénonlittéraux objet, configuration
as Tseulement « les types se recouvrent-ils »nonvous en savez plus que le compilateur
x!retire uniquement null / undefinednonvous savez qu'une valeur est définie
Type guard x is Tle corps du guard est du code ordinaireouidonnées venues de l'extérieur

Il reste deux bons usages de as : affiner quelque chose que le compilateur ne peut pas suivre (une entrée de Map que vous avez définie deux lignes plus haut, une valeur d'une bibliothèque non typée), et le code de test qui construit des fixtures partielles. Gardez-les petits et proches de l'endroit où vous savez que l'affirmation est vraie.

Questions fréquentes

Que fait as en TypeScript ?

value as Type est une assertion de type : elle demande au compilateur de traiter value comme un Type à partir de là. Elle est retirée du JavaScript compilé, elle n'effectue donc ni conversion ni vérification à l'exécution. Si l'assertion est fausse, le programme échoue plus tard, là où le mauvais type est utilisé.

Comment caster un type en TypeScript ?

TypeScript n'a pas de cast à l'exécution. Utilisez as (ou l'ancienne forme <Type>value) pour changer le type statique quand vous en savez plus que le compilateur. Pour réellement convertir une valeur, appelez une fonction : Number("42"), String(42), Boolean(x), new Date(text).

Que signifie « as unknown as » en TypeScript ?

Une double assertion. TypeScript refuse x as T quand les deux types ne se recouvrent pas du tout (erreur TS2352), et passer d'abord par unknown contourne cette vérification, car n'importe quoi peut être affirmé vers et depuis unknown. Cela désactive complètement la vérification des types pour cette valeur : réservez-le aux tests et au code où vous avez vérifié le type par un autre moyen.

Quelle est la différence entre as et les chevrons en TypeScript ?

Aucune sur le fond : <string>value et value as string sont la même assertion. La forme à chevrons ne peut pas être utilisée dans les fichiers .tsx, car elle entre en conflit avec JSX : as est donc la forme que tout le monde utilise.

Quelle est la différence entre as et satisfies ?

as remplace le type inféré et vérifie très peu de choses (les propriétés manquantes sont autorisées). satisfies vérifie la valeur par rapport à un type, en signalant les propriétés manquantes ou en trop, et garde le type inféré précis. Préférez satisfies pour les littéraux objet, et as uniquement quand vous en savez vraiment plus que le compilateur.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER