HOLY COW, GUZY, you can customize TypeScript compiler errors now! Well… you probably could before, but… not easily. This new TypeScript 7.1 API allows you to get info about what the compiler found, and translate it to … you know, English.
Elm did that. Rust became popular, but people were like “this ain’t English, bruh” so then they copied Elm. Now, finally, tooling for TypeScript can copy Elm.
k, but what’s a specific use case beyond “leveling up TypeScript” you may ask? Great question! For the past few months, I’ve been building tooling around improving cyber security for logs; e.g. ensuring we don’t leak sensitive customer or passwords into our logs.
Most dynamic languages, AND typed languages, will use substring and regex searches in sinks; e.g. where your data leaves your application through a log (console.log, AWS Power Tools, pino, etc). This ensures “the 1 place it exits, we ensure no NPI/PCI leaks occur”. Rad.
… but devs who are into types are like “wait a minute, wait a minute… ‘if it compiles, it works’ if that’s true… then why can’t we ‘if it compiles, it’s safe’?” So they, and me, will leverage types to ensure:
- sensitive data is typed; could be a Brand, Product, Union… whatever
- sinks (e.g. logs) do not allow sensitive data
You could do that via types, type proofs, both. So cool, we can now “If it compiles, it is safe”, BUT ALSO “because TypeScript gradually typed and not sound” still have the runtime redaction too.
Except there is one problem: the compiler error messages are trash. Let’s see an example. Below, we’re creating an American Social Security Number (aka ssn) as a Sensitive data brand type. We’re then creating a log function that doesn’t allow it ssn’s to be logged.

So that’s cool; you can see in the image that ssn isn’t compiling when you pass it as a parameter to the log function.
However, what’s NOT cool is the compiler error you get for it: “Type ‘Sensitive‹string, “Social Security Number”›’ is not assignable to type ‘undefined’.”

So never is weird; it’s even weird in Elm. However, it’s used a lot more in TypeScript so you can assert a compiler error. Sometimes, as you can see, the error doesn’t even say never, it says undefined. That said, it still sounds weird when you say that compiler out loud. Usually from a Domain Driven Design perspective you’d be like “A can’t be B” or “a PendingAccount cannot be a ConfirmedAccount”. But… “Cow can’t be assigned to never/undefined” like… wat?
ENTER TYPESCRIPT 7.1 COMPILER API (e.g. import typescript/sync). You can get all the diagnostic errors, and if it’s one you recognize, like “Sensitive SSN to never” you can map it to “Social Security Numbers cannot be logged”

SO BALLER
Leave a Reply