L'annotation vérifie mais élargit. Le as garde mais ne vérifie pas.The annotation checks but widens. The as keeps but doesn't check.
Pour une valeur qu'on écrit soi-même — un objet de config, une palette, une table de routes — on veut deux choses : qu'elle respecte une forme attendue, et qu'on garde le type précis que TypeScript infère (les clés exactes, le type fin de chaque propriété). L'annotation donne la vérification mais élargit tout vers le type déclaré. Le as garde la forme mais ne vérifie rien et peut mentir. On est coincé entre sûreté-sans-précision et précision-sans-sûreté — jusqu'à satisfies, épaulé d'un as const quand on veut aussi figer les littéraux.For a value you write yourself — a config object, a palette, a route table — you want two things: that it respects an expected shape, and that you keep the precise type TypeScript infers (the exact keys, each property's narrow type). The annotation gives the check but widens everything to the declared type. The as keeps the shape but checks nothing and can lie. You're stuck between safety-without-precision and precision-without-safety — until satisfies, backed by as const when you also want the literals frozen.
// annotation : vérifie, mais ÉLARGIT — clés exactes et littéraux perdus const routes: Record<string, string> = { home: "/", admin: "/admin" }; routes.home; // string (pas "/") — précision perdue routes.typo; // string — aucune erreur sur une clé inventée ! // as : garde la forme voulue, mais NE VÉRIFIE PAS const r2 = { home: "/" } as Record<"home" | "admin", string>; // admin manque — passe quand même
satisfies fait ce qu'aucun des deux ne sait : il contrôle la conformité (comme l'annotation) tout en conservant le type le plus précis (comme l'inférence nue) — sans rien forcer ni élargir.satisfies does what neither can: it checks conformance (like the annotation) while keeping the most precise type (like bare inference) — forcing and widening nothing.
// as const (Vol 4.3) fige les littéraux ; satisfies vérifie la forme const routes = { home: "/", admin: "/admin" } as const satisfies Record<string, string>; routes.home; // "/" — littéral conservé (par as const) routes.typo; // ✗ 'typo' n'existe pas — satisfies a gardé les clés exactes // et une clé manquante, ou { admin: 42 }, serait refusée : la conformité EST vérifiée
« Je veux contrôler sans perdre la précision → satisfies, pas as. » Là où l'on dégainait un as pour « faire respecter » une forme, on voulait presque toujours vérifier, pas forcer."I want to check without losing precision → satisfies, not as." Where you reached for an as to "enforce" a shape, you almost always meant to verify, not force.
La frontière ment (7.1) ; on parse la donnée reçue (7.2) ; et pour les valeurs qu'on écrit soi-même, satisfies remplace le as par une vérification qui garde la précision (7.3). Les deux derniers numéros se répartissent le travail : parse pour ce qui entre, satisfies pour ce qu'on rédige. Et satisfies referme la question du as ouverte au Vol 4.The boundary lies (7.1); you parse received data (7.2); and for the values you write yourself, satisfies replaces as with a check that keeps precision (7.3). The last two issues split the work: parse for what comes in, satisfies for what you author. And satisfies closes the as question opened in Vol 4.