I’m a fan of the Runtypes library for this use case. If you design your typescript interfaces using the library (admittedly a bit magical to me) you can get runtime errors if API data doesn’t match the expected type
But since it isn’t, augmentations may be an option. I’m not at my computer right now so I can’t verify that this would work, but you may be able to add an overload that returns `unknown`. Unfortunately with overloads, I’m pretty sure the built in types would be selected first without some additional specificity.
This feels like a good opportunity for a safer standard library package wrapping globals, DOM, Node built-ins, etc.
[1] https://www.typescriptlang.org/play?#code/PTAEEkDsDMFMCd6wCa...
https://github.com/microsoft/TypeScript/blob/master/lib/lib....
You could provide your own lib.d.ts with `unknown` type returned for JSON.parse. I'm almost surprised there isn't a standard stricter lib.d.ts, though I suppose that linters fill enough of those needs with their rulesets.
Looking at GitHub issues surrounding it, it doesn't appear that there has been an explicit ask to switch the type signature to use `unknown`, probably the next closest was this one, where `unknown` is mentioned in a comment as a possibility but the comment is not addressed in follow up discussion: https://github.com/microsoft/TypeScript/issues/26993
It would be a big breaking change though at this point, so they would probably be hesitant to do so. I thought I saw somewhere there was a proposal to add it as a compiler flag to treat all uses of `any` in lib.d.ts as `unknown`, but I have no idea what happened to that proposal and quick searches don't turn up anything.
The point of type-safety is to be able to describe more succinctly what the _programmer_ expects out of the code. As you said, when you get to production, "all bets are off". This still applies with any type-safe language. Types don't exist when you're compiling to machine code, either.
I'm not sure it is; the most dangerous things in programming are assumptions that are almost correct, so you don't notice the problem until it's too late. An error whose symptom is an Int actually being a String several files away from where the mistake actually happened can be harder to diagnose than the same error in a untyped language, just because it's so contrary to your expectation.
- Catch more errors at compile time
- Better tooling (better intellisense, “go to definition”, “find implementations”, etc.)
TypeScript provides both of these benefits just fine. Runtime types give you better runtime errors, and less undefined behaviour, but plain JS (or TS compiled to JS) does that bit just fine. TS types persisting at runtime could maybe be nice for certain use cases, like more powerful reflection, but that’s not type safety.
What’s a concrete example where your program would be more safe if TypeScript types were represented at runtime?
It also encourages better architecture in my opinion, as it forces you to reduce the importance of something being an exact type... As it's not strictly enforced at runtime.