Le test marche. Mais sorti dans une fonction, la preuve reste à l'intérieur.The test works. But pulled into a function, the proof stays inside.
Le narrowing du numéro précédent vivait dans un if, sur place. Dès qu'on factorise ce test dans une fonction, le type rétréci s'évapore : un retour boolean dit seulement « vrai ou faux », jamais « et donc x est un string ». Le prédicat de type x is string est la seule façon de faire voyager cette preuve à travers la frontière de la fonction.The narrowing of the previous issue lived in an if, on the spot. The moment you factor that test into a function, the narrowed type evaporates: a boolean return only says 'true or false', never 'and therefore x is a string'. The type predicate x is string is the only way to carry that proof across the function boundary.
function isString(x: unknown): boolean { // ': boolean' écrit à la main — sans lui, return typeof x === "string"; // TS 5.5+ inférerait x is string (voir ch. 3) } function f(x: unknown) { if (isString(x)) { x.toUpperCase(); // ✗ x est toujours 'unknown' — boolean ne dit pas QUOI } }
Un boolean répond à la question mais oublie ce qu'il a appris. Le prédicat x is string emporte la conclusion avec lui — le narrowing reprend de l'autre côté de l'appel.A boolean answers the question but forgets what it learned. The predicate x is string takes the conclusion with it — narrowing resumes on the far side of the call.
function isString(x: unknown): x is string { return typeof x === "string"; } function f(x: unknown) { if (isString(x)) { x.toUpperCase(); // ✓ x : string — la preuve a traversé la fonction } }
« Cette fonction qui teste — rend-elle un simple oui/non, ou une preuve réutilisable ? » Si le résultat doit rétrécir un type chez l'appelant, son retour doit être un prédicat, pas un boolean."This function that tests — does it return a plain yes/no, or a reusable proof?" If the result must narrow a type for the caller, its return must be a predicate, not a boolean.
L'effacement a posé le problème (le type s'évapore), le narrowing a montré comment le compilateur reconstruit une preuve sur place. Restait à la rendre transportable — réutilisable, nommée, partagée. Le type guard est ce dernier maillon : la preuve devient une fonction.Erasure posed the problem (the type evaporates), narrowing showed how the compiler rebuilds a proof on the spot. What remained was making it portable — reusable, named, shared. The type guard is that final link: the proof becomes a function.