4 ms·
For me, the main place the issue above rears it’s head is in data retrieved from an API. A strongly-typed language would fail loudly and predictably if a blob o
by Townley 6y ago
For me, the main place the issue above rears it’s head is in data retrieved from an API. A strongly-typed language would fail loudly and predictably if a blob of JSON didn’t match the expected format. In some situations, that’s preferable to having invalid data work it’s way through the system, or having to manually implement type checking
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
- neurotrace 6y agoYou can use guard functions to validate external data. This same problem comes up in other statically typed languages. You can't guarantee that external data will be in the shape that you expect so you must validate it. If you're just taking your `unknown` API response and immediately casting it to your desired type then that's your fault, not TS
- eropple 6y agoThat's what runtypes is.
- fy20 6y agoYou can use something like io-ts or zod to validate external data at runtime.
- Vinnl 6y agoYeah, ideally JSON.parse() returned `unknown`, but unfortunately that was added after the current type definition was already in widespread use, and therefore would be too much of a breaking change. Perhaps some day with a compiler flag.
- TheCoelacanth 6y agoIsn't that basically what the noImplicitAny flag does?
- Vinnl 6y agoUnfortunately no: that only errors when you do not add a type annotation and TypeScript can't infer anything better than `any`. JSON.parse(), however, is explicitly annotated to return any. See [1]. [1] https://www.typescriptlang.org/play?#code/PTAEEkDsDMFMCd6wCagC4HtQCNagIaQCeo08GAtqAFIDKA8gHIB0ADvvAM6wDknosAB6sANgEsAxmLSgkaAK7xI6Iq1gAuAFASMkTjMIBRQfgqjYANQ5j82EXgC8NBi3ZdYACgBEACVgiRLAB1DHgRZC8ASgBubV1ODHtmQIBzDyMTM3sreBs7WBjNTRAIGAQkVEwcPEISXAl8eW50AAsEPDF+SAw0FrFIFPQsfrh4Vrw0VTwySi1oeUgJNDFddFh9DzEsyWkRIgBBYkjQAG9NUAvQHT1E2GSMNK3RHbQ9w6JCgF9NIA https://www.typescriptlang.org/play?#code/PTAEEkDsDMFMCd6wCa...
- WorldMaker 6y agoYes, the type signature for JSON.parse() isn't inferred/deduced, it's explicit in lib.es5.d.ts (imported from lib.d.ts): https://github.com/microsoft/TypeScript/blob/master/lib/lib.es5.d.ts#L1059 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 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.
- Vinnl 6y agoYeah I'd swear I'd seen that too, but I can't find it quickly either.
- TheCoelacanth 6y agoAh, I see my mistake. I have been getting warnings about JSON.parse, but they are coming from eslint@typescript-eslint/no-unsafe-assignment. It partially serves this purpose, but probably not as comprehensively as actually having it return unknown would.
- eyelidlessness 6y agoThere are a lot of core language types that could substantially improve safety (not to mention inference), with anything explicitly `any` being obvious candidates. I feel like this should be a compiler/lib option for those of us who would opt into the breaking change for increased safety. 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.