Vol. 4 · № 02 · Un atelier TypeScriptA TypeScript workshop

unknown, l'inconnu honnête, ou je ne sais pas, alors prouve-le unknown, the honest unknown, or I don't know, so prove it

unknown dit la même chose qu'any — « je ne connais pas ce type » — mais ferme la porte à clé au lieu de l'arracher. Tout monte dans unknown, rien n'en redescend sans preuve : impossible de lire, d'appeler, d'assigner, sans avoir d'abord rétréci. C'est le type top, miroir du never. Le défaut honnête au catch et à la frontière — à condition de le franchir par un check, jamais par un as. unknown says what any says — 'I don't know this type' — but locks the door instead of tearing it off. Everything flows up into unknown, nothing flows back down without proof: you can't read, call, or assign before narrowing. It's the top type, the mirror of never. The honest default in catch and at the boundary — provided you cross it by a check, never an as.

AudienceAudience
Dev qui a vu le trou d'any et veut l'aveu honnête qui force la preuve Dev who saw any's hole and wants the honest admission that forces proof
Format
Self-paced
ChapitresChapters
5
Date
Juin 2026 Jun 2026
≈ 18 min ●●○○ unknownNarrowingTradeoff
SommaireContents ·
№ 01CadrageFraming3 min

Même aveu qu'any — « je ne connais pas ce type » — mais unknown refuse qu'on s'en serve.Same admission as any — "I don't know this type" — but unknown refuses to let you use it.

Le numéro précédent a montré le trou. Voici son jumeau honnête. unknown dit exactement la même chose qu'any : « le type de cette valeur m'échappe ». Mais là où any te laisse agir à l'aveugle — et le bug revient au runtime — unknown ferme la porte : tant que tu n'as pas prouvé ce que tu tiens, tu ne peux rien en faire. Le cas canonique, c'est le catch : une exception peut être n'importe quoi, et seul unknown t'oblige à le reconnaître.The previous issue showed the hole. Here's its honest twin. unknown says exactly what any says: 'I don't know this value's type'. But where any lets you act blindly — and the bug returns at runtime — unknown shuts the door: until you've proven what you hold, you can do nothing with it. The canonical case is catch: an exception can be anything, and only unknown forces you to admit it.

catch (e: any) — l'aveugle qui plante dans le catchcatch (e: any) — the blind path that crashes in the catch
try {
  risky();
} catch (e: any) {                  // any : on fait ce qu'on veut de e
  console.log(e.message.toUpperCase());
  //          ^ et si le code a fait 'throw "panne"' ou 'throw 42' ?
}                                   // 💥 e.message est undefined — crash dans le catch
Même ignorance, deux portesSame ignorance, two doors
any
la porte arrachéethe door torn off
agis à l'aveugle — 💥 au runtimeact blindly — 💥 at runtime
unknown
la porte fermée à cléthe locked door
prouve d'abord, agis ensuiteprove first, act after

Les deux avouent ne pas connaître le type. any en conclut « alors fais ce que tu veux » ; unknown, « alors tu ne fais rien avant de l'avoir prouvé ». La même ignorance, retournée en garde.Both admit they don't know the type. any concludes "then do whatever"; unknown, "then you do nothing until you've proven it". The same ignorance, turned into a guard.

catch (e: unknown) — prouve avant de touchercatch (e: unknown) — prove before you touch
try {
  risky();
} catch (e: unknown) {              // unknown : on ne peut RIEN faire sans prouver
  if (e instanceof Error) {
    console.log(e.message.toUpperCase());   // ✓ ici e : Error — prouvé
  } else {
    console.log("erreur non-Error :", e);   // l'autre cas, géré honnêtement
  }
}
Le réflexe du numéroThe issue's reflex

« Je ne connais pas ce type — est-ce que je l'assume (unknown, et je prouve) ou est-ce que je le cache (any, et je prie) ? » Dès qu'une valeur arrive sans garantie, unknown est le défaut honnête : il transforme l'ignorance en obligation de preuve."I don't know this type — do I own it (unknown, and I prove) or hide it (any, and I pray)?" The moment a value arrives without a guarantee, unknown is the honest default: it turns ignorance into an obligation to prove.

Le jumeau, pas l'opposé.The twin, not the opposite.

any et unknown partent du même constat — type inconnu — et divergent sur la conséquence. C'est pourquoi unknown ne « remplace » pas any par magie : il rend visible le travail qu'any escamotait. Tout le numéro tient dans ce déplacement : de « débrancher la vérification » à « différer l'usage jusqu'à la preuve ».any and unknown start from the same finding — unknown type — and diverge on the consequence. That's why unknown doesn't magically 'replace' any: it makes visible the work any concealed. The whole issue lives in that shift: from 'unplug the check' to 'defer use until proof'.

№ 02La surpriseThe surprise4 min

Sur un unknown nu, rien ne compile. Pas même .toString().On a bare unknown, nothing compiles. Not even .toString().

Premier contact, on le trouve hostile : impossible de lire une propriété, d'appeler, d'additionner, ni même d'assigner à un type. Le compilateur refuse tout. C'est exactement l'inverse d'any, et c'est voulu. any est assignable dans les deux sens — tout y monte, et il redescend partout. unknown n'est assignable que dans un sens : tout y monte, mais il ne redescend dans rien. Cette asymétrie est tout le mécanisme : elle force la preuve avant l'usage.First contact, you find it hostile: you can't read a property, call it, add to it, or even assign it to a type. The compiler refuses everything. It's the exact opposite of any, and it's deliberate. any is assignable both ways — everything flows up, and it flows back down everywhere. unknown is assignable one way only: everything flows up, but it flows back down into nothing. That asymmetry is the whole mechanism: it forces proof before use.

Tout usage est refusé tant qu'on n'a pas prouvéEvery use is refused until you've proven
const x: unknown = getValue();

x.foo;          // ✗ 'x' is of type 'unknown'
x();            // ✗ 'x' is of type 'unknown'
x + 1;          // ✗ 'x' is of type 'unknown'
x.toString();   // ✗ même ça : RIEN n'est permis sans preuve
const s: string = x;   // ✗ unknown ne redescend dans aucun type

Le « mur » n'est pas une punition, c'est la garantie : tant que tu n'as rien prouvé, tu ne peux rien casser. Chaque ligne refusée est une question que le compilateur te pose — « es-tu sûr que c'est un objet ? une fonction ? un nombre ? » — et qu'il t'oblige à répondre avant d'agir.The "wall" isn't a punishment, it's the guarantee: as long as you've proven nothing, you can break nothing. Each refused line is a question the compiler asks you — "are you sure it's an object? a function? a number?" — and forces you to answer before acting.

Tout type monte dans unknown ; unknown ne redescend dans aucun. Cette porte à sens unique est ce qui sépare l'inconnu honnête du trou.Every type flows up into unknown; unknown flows back down into none. That one-way door is what separates honest unknown from the hole.
№ 03La mécaniqueThe mechanics5 min

On ouvre un unknown par narrowing — le Vol 2, réemployé comme clé.You open an unknown by narrowing — Vol 2, reused as the key.

Le mécanisme pour sortir du mur est exactement celui du Vol 2 : rétrécir. typeof pour les primitives, instanceof pour les classes, in et les type guards pour les objets. Chaque test fait passer x d'unknown à un type concret, et débloque ce qu'on peut faire avec dans la branche. unknown est le type top — le supertype de tout —, exactement le miroir de never, le type bottom du 3.2. L'un dit « ça peut être n'importe quoi », l'autre « ça ne peut rien être ».The mechanism for leaving the wall is exactly Vol 2's: narrowing. typeof for primitives, instanceof for classes, in and type guards for objects. Each test moves x from unknown to a concrete type, and unlocks what you can do with it in the branch. unknown is the top type — the supertype of everything — exactly the mirror of never, the bottom type from 3.2. One says 'it can be anything', the other 'it can be nothing'.

Le narrowing ouvre l'unknown, branche par brancheNarrowing opens the unknown, branch by branch
function len(x: unknown): number {
  if (typeof x === "string") return x.length;       // x : string
  if (Array.isArray(x))      return x.length;        // x : unknown[]
  if (x instanceof Set)      return x.size;          // x : Set<unknown>
  return 0;                                          // tous les autres cas
}
Les deux pôles : unknown (top) et never (bottom)The two poles: unknown (top) and never (bottom)
// unknown et never sont les deux pôles du système de types :
declare const top: unknown;    // TOUT est un unknown      (le supertype universel)
declare const bottom: never;   // RIEN n'est un never       (le sous-type universel)
const x: unknown = bottom;     // ✓ never → unknown
const y: never = top;          // ✗ unknown ne redescend nulle part, never encore moins
Comment ouvrir un unknownHow to open an unknown
La cléThe key
PrimitivePrimitivetypeof x === "string"
ClasseClassx instanceof Error
ObjetObject"id" in x / type guard"id" in x / type guard
Ce que ça débloqueWhat it unlocks
Dans la brancheIn the branchle type concret, vérifiéthe concrete, checked type
Hors brancheOutside ittoujours unknown : rienstill unknown: nothing
La frontièreThe boundaryle bon type pour JSON.parse (Vol 7)the right type for JSON.parse (Vol 7)
Les voisins, seulement nommés.The neighbors, only named.

Le drapeau useUnknownInCatchVariables (dans strict) rend catch (e) de type unknown plutôt qu'any — c'est lui qui force la garde du chapitre 1. JSON.parse et fetch().json() renvoient hélas any : les retyper en unknown rebranche la vérification (Vol 7). À ne pas confondre avec object (« un objet, pas un primitif ») ni {} (« tout sauf null/undefined ») : unknown est le seul vrai « je ne sais rien ».The useUnknownInCatchVariables flag (in strict) makes catch (e) of type unknown rather than any — it's what forces chapter 1's guard. JSON.parse and fetch().json() sadly return any: retyping them to unknown re-wires the check (Vol 7). Don't confuse it with object ("an object, not a primitive") or {} ("anything but null/undefined"): unknown is the only true "I know nothing".

№ 04Le piègeThe trap4 min

Rétrécir un unknown avec as, c'est rouvrir le trou — en plus cérémonieux.Narrowing an unknown with as reopens the hole — just more ceremoniously.

unknown ne vaut que par le mur qu'il dresse. Et il y a une façon de le contourner sans le franchir honnêtement : le caster. as User ne prouve rien — il affirme. La valeur n'a pas été vérifiée, le compilateur se tait parce qu'on le lui a ordonné, et le crash revient comme avec any. On a payé la cérémonie d'unknown sans en toucher la garantie : le pire des deux mondes.unknown is only worth the wall it raises. And there's a way around it without honestly crossing it: casting. as User proves nothing — it asserts. The value wasn't checked, the compiler goes quiet because you ordered it to, and the crash returns just like with any. You paid unknown's ceremony without getting its guarantee: the worst of both worlds.

Le as qui saute le mur sans le franchirThe as that vaults the wall without crossing it
const data: unknown = JSON.parse(raw);

const user = data as User;        // ✗ on n'a rien prouvé — juste affirmé
console.log(user.name.trim());    // 💥 si data n'a pas de .name : crash
// unknown rétréci par 'as' = any avec deux mots de plus. Le mur est contourné.

Le as User dit au compilateur « crois-moi », sans le moindre contrôle à l'exécution. C'est exactement le type guard menteur du 2.3, et le retour silencieux d'any du numéro précédent. Le contre-exemple obligatoire : unknown suivi d'un as non justifié n'apporte rien — autant assumer le trou.The as User tells the compiler "trust me", with zero runtime check. It's exactly the lying type guard of 2.3, and the silent return of any from the previous issue. The mandatory counter-example: unknown followed by an unjustified as brings nothing — you may as well own the hole.

L'autre excès : l'unknown partout.The other excess: unknown everywhere.

Le miroir du sur-branding du 3.3 : semer des unknown à l'intérieur de son propre code, là où l'on connaît le type, n'achète aucune sûreté — juste la friction de re-narrower sans cesse. unknown est l'outil de la frontière (entrées réseau, catch, JSON.parse), pas une façon d'esquiver l'effort de typer ses propres fonctions. Là où tu sais, écris le vrai type.The mirror of 3.3's over-branding: scattering unknown through your own code, where you do know the type, buys no safety — just the friction of re-narrowing endlessly. unknown is the tool of the boundary (network input, catch, JSON.parse), not a way to dodge the effort of typing your own functions. Where you know, write the real type.

Le mur d'unknown ne protège que si on le franchit. Le contourner par un as, c'est repeindre le trou aux couleurs de la sûreté.The unknown wall only protects if you cross it. Skirting it with an as is repainting the hole in the colors of safety.
№ 05Bilan & éditoWrap-up & editorial2 min

L'ignorance, mais déclarée — et qui se paie en preuves.Ignorance, but declared — and paid in proofs.

unknown est le jumeau honnête d'any : même aveu — type inconnu — mais une porte fermée à clé plutôt qu'arrachée. Tout monte dans unknown, rien n'en redescend sans preuve : le mur force le narrowing avant tout usage. C'est le type top, miroir exact du never bottom. Le défaut juste à toute frontière — à condition de franchir le mur par un check, pas par un as.unknown is any's honest twin: same admission — unknown type — but a locked door rather than a torn-off one. Everything flows up into unknown, nothing flows back down without proof: the wall forces narrowing before any use. It's the top type, exact mirror of the bottom never. The right default at every boundary — provided you cross the wall by a check, not an as.

Tu veux…You want to…Le gesteThe moveCe que ça coûteWhat it costs
Tenir une valeur de type inconnuHold a value of unknown typeunknown — le top type qu'on doit prouver.unknown — the top type you must prove.Narrowing obligatoire avant tout usage.Narrowing required before any use.
Typer un catch / JSON.parseType a catch / JSON.parseunknown, puis narrowe (vs any par défaut).unknown, then narrow (vs any by default).Un peu de cérémonie à la frontière — assumée.A touch of ceremony at the boundary — owned.
Ouvrir un unknownOpen an unknowntypeof / instanceof / in / type guard (Vol 2).typeof / instanceof / in / type guard (Vol 2).Il faut un vrai check — un as ne prouve rien.A real check is needed — an as proves nothing.
Ne PAS l'employerNOT use itLà où tu connais déjà le type.Where you already know the type.Friction pour rien — annote le vrai type.Friction for nothing — annotate the real type.
any répond « ne t'en fais pas » ; unknown répond « prouve-le ». La sûreté est dans la seconde réponse — et dans le travail qu'elle te demande.any answers "don't worry about it"; unknown answers "prove it". Safety is in the second answer — and in the work it asks of you.
Mot de l'éditeurFrom the editor

« Je ne sais pas — alors prouve-le. »"I don't know — so prove it."

any et unknown partent du même endroit — une valeur dont on ignore le type — et c'est leur réponse qui les sépare. any fait comme si la question ne se posait pas : agis, je ne regarde pas. unknown rend l'ignorance explicite et refuse de te laisser agir tant que tu ne l'as pas levée. Le mur qu'on trouve hostile au premier contact est précisément la garantie : tant que tu n'as rien prouvé, tu ne peux rien casser. C'est le type top, le miroir exact du never du Vol 3 — l'un dit « ça pourrait être n'importe quoi, ne suppose rien », l'autre « ça ne peut rien être ». Entre les deux, tout le travail de narrowing du Vol 2 reprend son sens : la preuve se reconstruit branche par branche, à partir de l'aveu honnête de départ.any and unknown start from the same place — a value whose type you don't know — and it's their answer that separates them. any pretends the question doesn't arise: act, I'm not looking. unknown makes the ignorance explicit and refuses to let you act until you've lifted it. The wall you find hostile at first contact is precisely the guarantee: as long as you've proven nothing, you can break nothing. It's the top type, the exact mirror of Vol 3's never — one says 'it could be anything, assume nothing', the other 'it can be nothing'. Between them, all of Vol 2's narrowing work regains its meaning: the proof rebuilds branch by branch, from the honest admission you started with.

Reste un raccourci tentant. Pour quitter le mur, on doit prouver — mais on peut aussi tricher, en disant simplement au compilateur « c'est un User », sans rien vérifier. Ce mot, c'est as, et il mérite son propre numéro : ni any qui débranche tout, ni unknown qui exige une preuve, mais le contrat qu'on signe à la place du compilateur — « tais-toi, je sais mieux ». Le dernier recours du volume, le plus mal compris, et celui sur lequel reposait déjà, en silence, le brand du Vol 3.One tempting shortcut remains. To leave the wall, you must prove — but you can also cheat, simply telling the compiler 'it's a User', checking nothing. That word is as, and it deserves its own issue: neither any that unplugs everything, nor unknown that demands a proof, but the contract you sign in the compiler's place — 'be quiet, I know better'. The volume's last resort, the most misunderstood, and the one Vol 3's brand already silently rested on.