Hacker News new | past | comments | ask | show | jobs | submit login

It's a neat library, but you end up defining your types in an external (outside of TS) syntax, and you lose a lot of language-server features. Also, last I checked it could not handle generics. But it's been a while.



You don’t lose any language server features, you just access them slightly differently. Each function in io-ts, zod, and other TS libraries like them) are type guards, and have companion utility types to extract the static types from their runtime definitions (with `typeof`). I’m certain that io-ts handles generics (I’ve used it to do so), albeit again slightly differently, in that you need to define them as generic type guards.

I think the clamor for runtime type checking in TS is partly because type guards and their benefits could be better explained at the language level, and partly that libraries implementing them effectively are mostly aimed at users who already understand those benefits.

You really don’t want pervasive runtime type checking, except at API boundaries where data is untyped (i.e. the appropriate type is `unknown`). Type guards are exactly designed for that use case. For other cases where the types are well known, runtime type checking is needlessly expensive and redundant.


Agree with all of that, but also, it's been at quite a while since I used it. I'm sure it's improved a lot since then, and my memory might be off as well. I really remember not being able to get it to work with generics. But maybe I didn't read the docs deep enough.

We just do what you describe now, and don't even really want automated type checking. We just write our own assertion functions. The weakness of writing your own is that you have to sort of "manually" upgrade them when there type changes, or they drift and your editor won't tell you about it.


If your editor isn’t telling you there’s a type error in your guard, that’s usually a good sign your guard is too large. Even if you’re rolling your own (which seems an odd choice but I’ll take it as read that you have reasons), it’s a good idea to take inspiration from the prior art. With libraries like zod/io-ts etc, it’s harder to end up with a mismatch like you describe than to always have your types and guards in sync, because the guards are built from small composable primitives and the types are derived from them. Larger guards built without that are basically a lot of ceremony around `as Foo`, with all the false sense of safety that implies.

Not trying to dissuade you from rolling your own, mind you. Heck, it’s been stalled for a while as I focus on other things, but I’m rolling my own whole library (also for reasons, foremost of which is handling JSON Schema generation and validation at runtime without relying on codegen like other solutions do).


It's not external to TS. You write your types by passing object literals to the functions that generate the validators; TypeScript then infers shockingly precise types, which can be extracted using TypeScript's type manipulation utilities.

It does support generics [0].

[0] https://github.com/gcanti/io-ts/blob/master/index.md#generic...


Sorry, I meant specifically the "syntax" of your type is not TS. It's those object literal constructions you mention.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: