Why TypeScript error codes aren't documented
Engineers who are new to TypeScript may find its errors to be cryptic. This post will help you understand them better.
Here’s some unsafe TypeScript code.
let greeting: string = null;Hover on greeting, and you’ll see the following:
Type 'null' is not assignable to type 'string'. (tsserver 2322)Pretend we’ve never used a type-safe language before, and we want to understand this error. What does it mean, and how do we fix it?
If we go to the TypeScript handbook and search for the error code “2322”, we’ll get zero results. Nothing directly explaining this error, or almost any error.
One idea you’ll see suggested online is to read this definition file from the TypeScript source code. Search that code, and you’ll find this the 2322 definition:
"Type '{0}' is not assignable to type '{1}'.": { "category": "Error", "code": 2322 }There’s no new information here. We’ve hit a wall.
Why won’t the TypeScript team make this easier, and what can we do in the meantime?
The “why” has several explanations. It:
- Avoids a documentation burden.
- Avoids inviting engineers to suppress errors.
- Acknowledges that errors are dynamic and hard to explain well.
Here’s brief summary of each. This is a bit of culture and history, supported by the issues and PR’s on the TypeScript repo.
The first reason this isn’t documented is that it avoids a costly maintenance burden. The TypeScript team considers error codes to be implementation details. Right now the error JSON definition file has 2,130 error codes. Maintaining docs for all of these would be a tremendous maintenance burden.
The second reason is that documenting these codes could encourage engineers to suppress them. This would be easier to do if each error had its own agreed-upon, citable definition. Read through the GitHub issues about this subject (here’s one example), and you’ll see this risk compared to disabling a malfunctioning fire alarm. Instead of fixing the problem, we ignore it by reducing (type) safety.
The third reason is that these messages are dynamic, so telling us what to do
about any one is harder than it sounds. To take our greeting example: what
should the developer do with this error? It’s debatable, and this is the easy
example.
Let’s look at our example again:
let greeting: string = null;Maybe we want a default assignment:
let greeting: string = 'hello'; // Type-safe!Or, maybe we want a union that reflects the null-ability:
let greeting: string | null = null; // Type-safe!I’d probably do the latter. This is the boring solution: you have to reason through the error and choose how to fix it.
One limitation: this works great for local assignability errors like 2322. It
works less well when the message is a symptom of a distant type, a bad
inference, or a third-party .d.ts file.
In those cases, widen the search: check the
inferred type
of the value being passed in, the generics on the function that produced it, and
whether strictNullChecks or another compiler flag changed the meaning of the
error.
- diagnosticMessages.json — TypeScript source
- Document error codes? (#38409) — TypeScript GitHub issue
- Compiler Options (strictNullChecks) — TypeScript docs