3 ms·
Regarding "don't use `x as Y` but instead use type guards". Type guards have a runtime overhead, don't they? (You could argue: "If TS can not infer the type a
by Garlef 6y ago
Regarding "don't use `x as Y` but instead use type guards".
Type guards have a runtime overhead, don't they?
(You could argue: "If TS can not infer the type at this point so neither can you. Better to check at runtime." But from my experience, sometimes TS is simply not smart enough.)
- throwanem 6y agoType guards do have a runtime overhead (since they're functions that get called), but so does any other method of validating untyped data at runtime. That's probably the 99% case with type guards, so I feel like the specific overhead on that isn't such a huge deal since anything else (e.g. runtypes) would probably have more. (I can think offhand of one case in the last year where I've wanted to use a type guard for a reason that didn't have to do with runtime validation, anyway. Even then, it wasn't the solution I ended up going with.)
- Garlef 6y agoOut of interest: What was the context where you needed the validation? In most contexts, the reasonable approach would be to only do runtime validation at your system boundaries and not anywhere inbetween.
- throwanem 6y agoThe case I mentioned didn't have to do with validation - in a case like that, I would have used a type guard, or more likely a runtype. This was a Javascript corner case that I hadn't previously encountered, where if you load the same module from two different paths, they aren't `instanceof`-equivalent. In this case, both the codebase of a module I was working on, and the codebase of one of its consumers, imported the same module from the same package, and I ran into the issue when I `npm link`-ed the module into its consumer's node_modules dir for testing and to ensure I hadn't inadvertently broken an implicit contract. The `instanceof` mismatch, between an object instantiated in module code and the class imported by the consumer, confused the type system and gave me spurious errors as a result. Thinking about how to solve this, it occurred to me to use a type guard, since it would have effectively convinced the type checker that my object instance was in fact an instance of the class of which it is an instance. But it would've been a wart and also imposed the aforementioned runtime overhead - not that that would've been meaningful in this case, it wasn't in a hot loop or anything, but I still didn't like it. So I ended up instead exporting the shared dependency from the module and having the consumer import it from there, rather than from its own (IIRC otherwise unused and thus eliminated) copy of the shared dependency.
- adamredwoods 6y agoDon't we mostly see this from json responses? The example they gave adds overhead, checking each product form an array. We use some responses with 200 products, we don't want this extra latency. Does JS need a better way to introduce json type safety? C# and graphql use schemas, I wonder if this is a better approach (compile time, not run time).
- Garlef 6y agoIf you're receiving JSON data, you can not validate the data at compile time. But yes: I think TS is missing a way to derive runtime functionality from the type definitions - at least in the cases, where the types describe plain JSON. Something along the lines of clojures' `spec`.
- jakelazaroff 6y agoYou can do the converse: create a type guard asserting a structure, and then extract a type. type Spec<T> = T extends (x: unknown) => x is infer U ? U : never; type Foo = Spec<typeof someTypeGuard>;
- deleted 6y ago[deleted]