[HN Gopher] Zod: TypeScript-first schema validation with static ...
       ___________________________________________________________________
        
       Zod: TypeScript-first schema validation with static type inference
        
       Author : tosh
       Score  : 84 points
       Date   : 2024-10-07 09:18 UTC (2 days ago)
        
 (HTM) web link (zod.dev)
 (TXT) w3m dump (zod.dev)
        
       | threatofrain wrote:
       | This is just a link to the front page of possibly the #1 most
       | popular type validation library in the ecosystem? Anyways, ya'll
       | might want to check out up-and-coming Valibot, which has a really
       | nice pipe API.
       | 
       | https://valibot.dev
        
         | sergiotapia wrote:
         | A whole lot of yapping and ZERO code on the homepage. Authors
         | should remove 90% of the stuff on that landing page, jesus!
         | 
         | also since zod is the de facto validation lib, might be worth a
         | specific page talking about why this vs zod. even their
         | migration from zod page looks nearly identical between the two
         | packages.
        
           | petesergeant wrote:
           | On the front page there is a prominent section addressing the
           | differences from Zod, which appear to be "much better
           | performance"
        
         | rjknight wrote:
         | Valibot is really nice, particularly for avoiding bundle size
         | bloat. Because Zod uses a "fluent builder" API, all of Zod's
         | functionality is implemented in classes with many methods.
         | Importing something like `z.string` also imports validators to
         | check if the string is a UUID, email address, has a minimum or
         | maximum length, matches a regex, and so on - even if none of
         | those validators are used. Valibot makes these independent
         | functions that are composed using the "pipe" function, which
         | means that only the functions which are actually used need to
         | be included in your JavaScript bundle. Since most apps use only
         | a small percentage of the available validators, the bundle size
         | reduction can be quite significant relative to Zod.
        
         | crooked-v wrote:
         | Valibot also has much, much more efficient type inference,
         | which sounds unimportant right up until you have 50 schemas
         | referencing each other and all your Typescript stuff slows to a
         | molasses crawl.
        
           | zztop44 wrote:
           | Agreed. I recently moved a production app from Zod to Valibot
           | for exactly this reason. I still slightly prefer Zod's syntax
           | but the performance issues were absolutely killing us.
        
         | Timon3 wrote:
         | I recently stumbled onto this when looking for alternatives,
         | and though it might sound a bit extreme: the style of
         | documentation means I'll never consider it for any project.
         | It's strange and honestly somehow unnerving to read
         | documentation written from a first-person perspective. Is there
         | some good reason for this that I'm missing? Or am I just crazy
         | and this isn't an issue for anyone else?
        
           | Bjartr wrote:
           | I only see second-person "you" and not first-person "I" in
           | the linked documentation. Am I missing what you intended to
           | point out?
           | 
           | In any case, this might actually be a good use for an LLM to
           | post-process it into whatever style you want. I bet there's
           | even a browser extension that could do it on-demand and in-
           | place.
        
             | Timon3 wrote:
             | Really? For example under "Main concepts" on the "Schemas"
             | site[0], I see stuff like this:
             | 
             | - I support the creation of schemas for any primitive data
             | type.
             | 
             | - Among complex values I support objects, records, arrays,
             | tuples as well as various other classes.
             | 
             | - For objects I provide various methods like pick, omit,
             | partial and required.
             | 
             | - Beyond primitive and complex values, I also provide
             | schema functions for more special cases.
             | 
             | Same for "Mental model", "Pipeline", "Parse data", "Infer
             | types", "Methods" and "Issues" - I'll assume the other
             | sections also follow this style. That's all not showing up
             | for you?
             | 
             | While the LLM suggestion is nice, it's not something I'm
             | comfortable with unless hallucinations are incredibly rare.
             | Why would I use a library whose documentation I have to
             | pass through an unreliable preprocessor to follow a normal
             | style?
             | 
             | [0]: https://valibot.dev/guides/schemas/
        
               | prophesi wrote:
               | If they're part of Hacktoberfest, editing those pages to
               | drop the first person perspective sounds like a pretty
               | useful first contribution.
        
               | Timon3 wrote:
               | It seems I'm not the first person to make this
               | observation: https://github.com/fabian-
               | hiller/valibot/issues/687
               | 
               | I honestly don't want my validation library to "tell a
               | story" at the expense of documentation clarity. It's
               | absolutely fine that this project uses it, I don't want
               | to impose my view on them - I guess it's just not the
               | validation library for me.
        
           | kaoD wrote:
           | > Or am I just crazy and this isn't an issue for anyone else?
           | 
           | Not an issue for me, to be honest. Why does it bother you at
           | all?
        
             | Timon3 wrote:
             | I'm not exactly sure myself, but every time I open one of
             | the pages, I mentally stumble over the formulations. I
             | think there are two components:
             | 
             | 1. The biggest part is that I've simply never seen
             | documentation written in this style, any mentions of "I" or
             | "we" are usually explaining the choices made by the
             | author(s). When skimming documentation I pay more attention
             | to those parts. Here those parts don't have a comparable
             | meaning.
             | 
             | 2. The smaller part is that the writing style reminds me of
             | the way brands use mascots with first-person writing to
             | advertise to children. There's not really any other
             | association I have with this way of writing, and it makes
             | me feel like the author either isn't taking the project
             | seriously, or me.
             | 
             | I'm not trying to argue that the documentation should be
             | understood this way, or that it should be changed - but
             | I've stumbled over this multiple times, and can't imagine
             | that it's just me.
        
           | skybrian wrote:
           | It's a little too cute, but I don't see it as a deciding
           | factor on which library to use.
           | 
           | I think a more important issue is that Valibot hasn't reached
           | 1.0 yet. But it looks like it's very close.
        
         | kaoD wrote:
         | Does/will this correctly handle `| undefined` vs `?`, i.e.
         | correct behavior under `exactOptionalPropertyTypes`?
         | 
         | Zod doesn't (yet[0]) and it's been a pain point for me.
         | 
         | [0] https://github.com/colinhacks/zod/issues/635
        
           | x1000 wrote:
           | I ran into exactly same pain point which was enough to
           | nullify the benefits of using zod at all.
        
         | mightyham wrote:
         | I'm currently using valibot and the author's associated modular
         | form library in a production app and can vouch that it's been
         | very pleasant to work with.
        
         | Eric_WVGG wrote:
         | Is Valibot's error handling any good? Zod's is... like
         | punishment for a crime I wasn't aware that I had committed.
        
         | hyperbrainer wrote:
         | Maybe OP is one of the lucky 10,000. https://xkcd.com/1053/
        
       | diggan wrote:
       | As someone who never jumped onto the TypeScript hype-wagon, what
       | is this for? Is this something like clojure.spec by for
       | TypeScript so you can do runtime validation of data instead of
       | compile-time validation?
       | 
       | Basically joi (https://joi.dev/api/?v=17.13.3) but different in
       | some way?
        
         | VoidWhisperer wrote:
         | Correct on the part of it being a runtime validation of data
         | library (I can't as easily speak to whether or not it is
         | similar to joi, never used it)
        
         | _fat_santa wrote:
         | I think the killer feature of Zod is type inference. Not sure
         | if Joi has support for it yet but you can take a zod schema and
         | wrap it in `z.infer` to get the typescript type.
         | 
         | Personally I use zod in my API for body validations, it's super
         | nice to write the schema then just use `type Body =
         | z.infer(schema)` to get the TS type to use inside the code.
        
           | threatofrain wrote:
           | That's table stakes for this niche.
        
         | naberhausj wrote:
         | I've not used either, but it appears to be similar to JOI, yes.
         | 
         | The main distinction is that ZOD allows you to extract a
         | TypeScript type from your schema. This means you get both
         | compile-time and run-time type checking.
        
         | valbaca wrote:
         | yep.
         | 
         | Typescript is build-time validation, but in the end TS is "just
         | JS"
         | 
         | Zod provides runtime validation (and also works well with TS)
        
           | molszanski wrote:
           | Deepkit.io has cool validations in runtime based on TS, but
           | it is whole another level.
        
         | newaccountman2 wrote:
         | > Is this something like clojure.spec by for TypeScript so you
         | can do runtime validation of data instead of compile-time
         | 
         | not really "instead", more like "in addition to". Even if your
         | code compiles, if you are receiving data, e.g., via API, then
         | you need to check that it actually conforms to the type/schema
         | you expect. What is run is JS, so it, sadly, won't just
         | crash/error if an object that is supposed to be of `type Cat =
         | {name: string, ownerId: number}` lacks an `ownerId` at runtime.
         | 
         | Have you used Pydantic in Python? It's like that, but feels
         | worse, IMO lol. I say this because Pydantic fits into writing
         | Python code much more naturally than writing Zod stuff fits
         | into writing TypeScript, IMO.
        
       | vorticalbox wrote:
       | At work I have used zod, myzod, joi though I have settled on
       | class-validator as it ties in with nestjs really well.
        
       | timpetri wrote:
       | Looking around on Twitter and repos in the OSS community, it
       | appears that Zod is now almost always favored over yup, despite
       | an almost identical API. Curious to hear what people think if
       | they've worked with both. We went with Yup early on at my
       | company, and now that's what we use for consistency in our
       | codebase. I haven't personally found it to be lacking, but some
       | of the logic around nulls and undefined always lead me back to
       | the docs.
        
         | roessland wrote:
         | My company used Yup initially but we moved to Zod to be able to
         | infer types from schemas. For example, API response payloads
         | are Zod schemas. OpenAPI components are also generated from Zod
         | schemas.
         | 
         | There are some performance issues, and WebStorm is struggling,
         | which forced me over to VS Code.
         | 
         | But overall pretty happy.
        
           | kabes wrote:
           | But Yup also allows to infer types from schemas...
        
       | psadri wrote:
       | One thing to note about zod - it clones objects as it validates
       | (parses) them. Eg z.array(z.object()) with an array of 10k
       | objects will result in 10k cloned objects - slow.
        
         | molszanski wrote:
         | I would suggest https://arktype.io/. Much faster on my project
        
       | leontrolski wrote:
       | For those of you from a Python background - this is basically
       | "Pydantic for Typescript". See also trpc - cross client/server
       | typing using zod under the hood - https://trpc.io/
        
       | brap wrote:
       | I always found it pretty awkward that you even need libraries
       | like this. A limitation of TS I suppose.
        
       | dhruvrajvanshi wrote:
       | I wonder about a Typescript with alternate design decisions. The
       | type system is cool and you can do a lot of compile time
       | metaprogramming. However, when there's a type error in computed
       | types, it's a nightmare to visually parse                 type {
       | foo: ... , bar: ..., ... } can't be assigned to type { foo: ...,
       | bar: ... }. type { foo: ... bar: ..., ... } is missing the
       | following properties from { foo: ..., bar: ..., ... }
       | 
       | Apart from repeating roughly the same type 4 times (which is a UX
       | issue that's fixable), debugging computed types requires having a
       | typescript interpreter in your head.
       | 
       | I wonder if we had nominal runtime checked types, it could work
       | better than the current design in terms of DX. Basically, the :
       | Type would always be a runtime checked assertion. Zod certainly
       | fills that gap, but it would be nicer to have it baked in.
       | 
       | The type system would not be as powerful, but when I'm writing
       | Kotlin, I really don't miss the advanced features of Typescript
       | at all. I just define a data class structure and add
       | @Serializable to generate conversions from/to JSON.
        
         | rlp wrote:
         | This is my exact experience. TypeScript seemed to hit a
         | complexity sweet spot about 5 years ago, then they just kept
         | adding more obscure stuff to the type system. I find that
         | understanding TypeScript compiler errors can be almost as
         | difficult as understanding C++ template errors at times.
        
           | phplovesong wrote:
           | This. Haxe is a more sane TS alternative in 2024.
        
             | jadbox wrote:
             | It's Haxe still been actively developed? I loved it back in
             | the day. The blog hasn't had an update in years.
        
         | wrs wrote:
         | TypeScript has a crazy powerful type system because it has to
         | be able to describe any crazy behavior that was implemented in
         | JavaScript. I mean, just take a look at @types/express-serve-
         | static-core [0] or @types/lodash [1] to see the lengths TS will
         | let you go.
         | 
         | If you write in TS to start with, you can use a more sane
         | subset.
         | 
         | [0]
         | https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...
         | 
         | [1]
         | https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...
        
           | dhruvrajvanshi wrote:
           | Right. I'm aware. My point was that even though the type
           | system is powerful, somehow, I'm able to represent everything
           | I need to in Kotlin's type system just fine and it feels a
           | lot more type safe because it will throw a type error at
           | runtime in the right place if I do a bad cast.
           | 
           | Typescript `as Foo` will not do anything at runtime, and it
           | will just keep on going, then throw a type error somewhere
           | else later (possibly across an async boundary).
           | 
           | You can, in theory use very strong lint rules (disallow `as`
           | operator in favour of Zod, disallow postfix ! operator), but
           | no actual codebase that I've worked on has these checks. Even
           | the ones with the strictest checks enabled have gaps.
           | 
           | Not to mention, there's intentional unsoundness in the type
           | system, so even if you wanted, you couldn't really create a
           | save subset of TS.
           | 
           | Then there's the issue of reading the library types of some
           | generic heavy code. When I "go to definition" in my fastify
           | codebase, I see stuff like this
           | RouteHandlerMethod<RawServer, RawRequest, RawReply,
           | RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider,
           | Logger>
           | 
           | Which expands to this                 export type
           | RouteHandlerMethod<       RawServer extends RawServerBase =
           | RawServerDefault,       RawRequest extends
           | RawRequestDefaultExpression<RawServer> =
           | RawRequestDefaultExpression<RawServer>,       RawReply
           | extends RawReplyDefaultExpression<RawServer> =
           | RawReplyDefaultExpression<RawServer>,       RouteGeneric
           | extends RouteGenericInterface = RouteGenericInterface,
           | ContextConfig = ContextConfigDefault,       SchemaCompiler
           | extends FastifySchema = FastifySchema,       TypeProvider
           | extends FastifyTypeProvider = FastifyTypeProviderDefault,
           | Logger extends FastifyBaseLogger = FastifyBaseLogger
           | 
           | > = ( this: FastifyInstance<RawServer, RawRequest, RawReply,
           | Logger, TypeProvider>, request: FastifyRequest<RouteGeneric,
           | RawServer, RawRequest, SchemaCompiler, TypeProvider,
           | ContextConfig, Logger>, reply: FastifyReply<RouteGeneric,
           | RawServer, RawRequest, RawReply, ContextConfig,
           | SchemaCompiler, TypeProvider> // This return type used to be
           | a generic type argument. Due to TypeScript's inference of
           | return types, this rendered returns unchecked. ) =>
           | ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler,
           | RouteGeneric>
           | 
           | Other languages somehow don't need types this complicated and
           | they're still safer at runtime :shrug:
        
             | rimunroe wrote:
             | > You can, in theory use very strong lint rules (disallow
             | `as` operator in favour of Zod, disallow postfix !
             | operator), but no actual codebase that I've worked on has
             | these checks. Even the ones with the strictest checks
             | enabled have gaps.
             | 
             | That's surprising. I've worked on a few codebases with
             | reasonably mature TS usage and they've all disallowed
             | as/!/any without an explicit comment to disable the rule
             | and explain why the use is required there.
        
             | wrs wrote:
             | It's apples and oranges. The type system in Kotlin is
             | integrated into the language. TypeScript is a preprocessor
             | for JavaScript that isn't allowed to change the JavaScript
             | language, or have any runtime.
             | 
             | The "as Foo" construct is for you to tell TS that you know
             | better than it, or that you deliberately want to bypass the
             | type system. You can have a runtime check, but you have to
             | write the code yourself (a type predicate), because TS
             | doesn't write or change any JavaScript*, it just type-
             | checks it.
             | 
             | I've certainly worked in new codebases where a relatively
             | simple subset of TS types were used. Even then there were a
             | few places the crazy type system was helpful to have. For
             | example, we enforced that the names of the properties in
             | the global configuration object weren't allowed to have
             | consecutive uppercase letters!
             | 
             | (* with minor exceptions like transpiling for new JS
             | features)
        
         | spencerchubb wrote:
         | Couldn't this be improved by showing a diff between the
         | mismatched types?
        
           | dhruvrajvanshi wrote:
           | Yes, I did mention that the UX of the type errors could be
           | improved and probably should, but once you start getting into
           | conditional types, and nested types (which may not be fully
           | expanded when you see the error), it gets hairy.
        
         | mhh__ wrote:
         | Can you do _any_ compile time metaprogramming in typescript?
        
       | molszanski wrote:
       | I very much enjoy more an alternative. Sadly much less hyped
       | https://arktype.io/
        
         | threatofrain wrote:
         | What do you like most about arktype?
        
       | aleksiy123 wrote:
       | Does anyone have a nice combination of tooling for typed handlers
       | + client generation.
       | 
       | Thinking maybe Zod + Zod open API.
       | 
       | Really looking to replicate similar spec first workflow similar
       | to protobuf services.
       | 
       | https://typespec.io/ also looks promising but seems early.
        
         | bjacobso wrote:
         | I think you are looking for https://ts-rest.com/
        
           | kaoD wrote:
           | Nice. I'm looking to migrate away from a legacy custom
           | framework over Express and this could help.
           | 
           | If someone has tried both, can anyone share how it compares
           | with tRPC[0]?
           | 
           | [0] https://trpc.io/
        
             | bjacobso wrote:
             | From my understanding trpc is very similar, however, the
             | rpc mechanism is not a standard. ts-rest produces openapi
             | schemas and speaks REST over http, as well as a typed
             | client.
             | 
             | That being said, I am actually slowly migrating off ts-rest
             | and adopting @effect/schema and @effect/platform/HttpApi, I
             | foresee this being the direction the typescript ecosystem
             | heads in over the next few years. However, the APIs are not
             | stable yet and it has a bit of a learning curve, so would
             | not adopt lightly
        
             | AWebOfBrown wrote:
             | I really wanted to adopt tRPC but the deal breaker was it
             | being opinionated on status codes without allowing
             | configurability. Because I needed to meet an existing API
             | spec, that meant ts-rest was a better option. I think
             | there's an aditional option with a native spec generator in
             | frameworks like Hono, and maybe Elysia.
        
         | mnahkies wrote:
         | My tool https://openapi-code-
         | generator.nahkies.co.nz/overview/about generates typed handlers
         | based around koa (routing, req/res validation using zod) from
         | openapi 3, as well as typed clients with optional zod
         | validation using fetch/axios.
         | 
         | It also supports typespec using their transpilation to openapi
         | 3 tooling
        
       | bearjaws wrote:
       | One of the brilliant decisions of the AI SDK from Vercel was to
       | use Zod.
       | 
       | It makes tool calling and chaining very robust, despite how
       | finicky LLMs can be.
        
       | bjacobso wrote:
       | zod is great, but I have been moving to @effect/schema and think
       | it deserves a mention here. @effect/schema is the evolution of
       | io-ts, which originally inspired zod.
       | 
       | It supports decoding as well as encoding, and fits natively into
       | the rest of the effect ecosystem.
       | 
       | https://effect.website/docs/guides/schema/introduction
       | 
       | It does come with the cost of importing effect, so might not be
       | the best in certain scenarios. However, there are smaller options
       | than zod if that is a concern.
        
         | obeavs wrote:
         | Yep. Effect is so cool. The ability encode AND decode is
         | tomorrow's standard.
         | 
         | With all the work they're doing on durable workflows, hard to
         | imagine that 2025 is anyone else's year.
        
       | dgellow wrote:
       | Zod is fantastic, we use it pretty extensively at Stainless.
       | Definitely one of my favorite JS library. Not calling it a parser
       | combinator was a really good marketing move
        
       | Stoids wrote:
       | The fragmentation around runtime validation libraries is pretty
       | crazy. The fact that half these comments mention some alternative
       | library that mimics almost the exact API of Zod illustrates that.
       | 
       | It is filling a necessary shortcoming in the gradual typing of
       | TypeScript, and using validator schema types to power other APIs
       | generic inference is powerful. I am optimistic about an obvious
       | leader emerging, or at least a better story about swapping
       | between them more easily, but a bit annoying when trying to pick
       | one to settle on for work that I have confidence in. That being
       | said, Zod seems like the community favorite at the moment.
        
         | skybrian wrote:
         | Yes, it's annoying. I share your optimism. This is how the
         | JavaScript (and now TypeScript) community figures things out.
         | 
         | Note that TypeScript had competitors, too. It got better. Zod
         | has an early lead and is good enough in a lot of ways, but I'm
         | not sure it will be the one.
         | 
         | Perhaps someday there will be a bun/deno-like platform with
         | TypeScript++ that has validation merged in, but it's probably
         | good that it's not standardized yet.
        
       | root_axis wrote:
       | I prefer typebox because it uses JSON schema. As far I'm aware
       | it's otherwise on par with Zod, but I might be unaware of some
       | capabilities of Zod that typebox lacks.
        
       | steve_adams_86 wrote:
       | I love Zod, but recently I've been converting to Effect's Data
       | and Schema modules.
       | 
       | Previously I liked a combination of Zod and ts-pattern to create
       | safe, pattern matching-oriented logic around my data. I find
       | Effect is designed far better for this, so far. I'm enjoying it a
       | lot. The Schema module has a nice convention for expressing
       | validators, and it's very composable and flexible:
       | https://effect.website/docs/guides/schema/introduction
       | 
       | There are also really nice aspects like the interoperability
       | between Schema and Data, allowing you to safely parse data from
       | outside your application boundary then perform safe operations
       | like exhaustively matching on tagged types (essentially
       | discriminated unions): https://effect.website/docs/other/data-
       | types/data#is-and-mat...
       | 
       | It feels extremely productive and intuitive once you get the hang
       | of it. I didn't expect to like it so much.
       | 
       | I think the real power here is that these modules also have full
       | interop with the rest of Effect. Effects are like little lazy
       | loaded logical bits that are all consistent in how they resolve,
       | making it trivial to compose and execute logic. Data and Schema
       | fit into the ecosystem perfectly, making it really easy to
       | compose very resilient, scalable, reliable data pipelines for
       | example. I'm a convert.
       | 
       | Zod is awesome if you don't want to adopt Effect wholesale,
       | though.
        
         | bjacobso wrote:
         | I've had a very similar experience, and have been slowly moving
         | from zod and ts-rest to @effect/schema and
         | @effect/platform/HttpApi as well as migration to Effect Match
         | from ts-pattern. There is a learning curve but its a pretty
         | incredible ecosystem once you are in it for a bit.
         | 
         | I think the real turning point was typescript 5.5 (May 2024).
         | The creator of typescript personally fixed a bug that unlocked
         | a more natural generator syntax for Effect, which I think
         | unlocks mainstream adoption potential.
         | 
         | https://twitter.com/MichaelArnaldi/status/178506160889445172...
         | https://github.com/microsoft/TypeScript/pull/58337
        
           | morbicer wrote:
           | I feel like Effect is today's Ramda. So cool but it's going
           | to be regretted by you and people coming after you in few
           | years. Me and my team reverted to more stupid code and we are
           | happier.
        
             | bjacobso wrote:
             | that is certainly a possibility
        
             | steve_adams_86 wrote:
             | I agree in some contexts. Kind of like Rust, I see a place
             | for more durable code that's harder to reason about in some
             | cases.
             | 
             | I wouldn't use Effect for a lot of things. For some things,
             | I'm very glad to have it. One thing Effect has going for it
             | that Ramda didn't is that it's much less abstract and it's
             | quite a bit more opinionated about some more complex
             | concepts like error handling, concurrency, or scheduling.
             | 
             | Kind of like state machines. You shouldn't use them for
             | everything. For some things, it's a bad idea not to (in my
             | opinion).
             | 
             | Then of course subjectivity is a factor here. Some people
             | will never like conventions like Effect, and that's fine
             | too. Just write what feels right.
        
           | steve_adams_86 wrote:
           | I agree about the turning point. Things have improved
           | dramatically. And I know it probably doesn't feel the same
           | for tons of people, but I love to see generators being used
           | in every day code.
           | 
           | The learning curve just about turned me away from it at the
           | start, but I'm glad I stuck with it.
           | 
           | I think learning Effect would actually teach a lot of people
           | some very useful concepts and patterns for programming in
           | general. It's very well thought out.
        
           | dimal wrote:
           | How did you find learning Effect? The sales pitch sounds
           | great, but when I went through the docs it seemed pretty
           | confusing to me. I'm sure there are reasons for the
           | everything but I couldn't grok it. In particular, I'm
           | thinking of the Express integration example.[0] I look at
           | that and think, I need all that just to create a server and a
           | route? What's the benefit there? I'm hesitant to buy into the
           | ecosystem after looking at that. I want to like it, though.
           | 
           | [0] https://effect.website/docs/integrations/express
        
             | theschwa wrote:
             | Yeah, looking at that example feels like jumping straight
             | into the deep end of the pool. I think it helps going
             | through a tutorial that breaks down the why of each piece.
             | I really liked this tutorial on it:
             | https://www.typeonce.dev/course/effect-beginners-complete-
             | ge...
             | 
             | Some core things from Effect though that you can see in
             | that Express example:
             | 
             | * Break things down into Services. Effect handles
             | dependency injection, that's typed, for services so you can
             | easily test them and have different versions running for
             | testing, production, etc. * Fibers for threaded execution *
             | Managing resources to make sure they're properly closed
             | with scope
             | 
             | I think a lot of these things though often aren't truly
             | appreciated until you've had something go wrong before or
             | you've had to build a system to manage them yourself. *
        
               | dimal wrote:
               | Yeah, this looks like the tutorial I needed. Thanks.
        
             | bjacobso wrote:
             | I agree, some of there examples are a little overly
             | complicated by their quest to be hyper composable. In fact
             | they should probably remove that example. I am currently
             | using it with Remix, and using their @effect/platform
             | package to produce a simple web handler (request: Request)
             | => Response (thank remix for heavily promoting the adoption
             | of web standards).
             | 
             | I fully agree parts of the ecosystem are complex, and
             | likely not fully ready for broad adoption. But I do think
             | things will simplify with time, patterns will emerge, and
             | it will be seen as react-for-the-backend, the de facto
             | first choice. effect + schema + platform + cluster will be
             | an extremely compelling stack.
        
       | BenoitP wrote:
       | And thus custom validation goes to json, completing a what is old
       | is new again cycle. After XML/XSD, after CORBA.
        
       | agluszak wrote:
       | Could someone explain to me what problem exactly Zod solves?
       | 
       | Why do you need to do `type User = z.infer<typeof User>;` instead
       | of declaring a class with typed fields and, idk, deriving a
       | parser for it somehow? (like you would with Serde in Rust for
       | example). I don't understand why Zod creates something which
       | looks like an orthogonal type hierarchy.
       | 
       | For context: I come from the backend land, I enjoy strong, static
       | typing, but I have very little experience with JS/TS and
       | structural typing
        
         | xmonkee wrote:
         | The User object in your example is used to parse the data. Its
         | the "somehow" part of your question. There is no way to go from
         | a type to data in typescript (there is no runtime awareness of
         | types whatsoever) so zod solves this by you writing the zod
         | object and then deriving the type from _it_. Basically you only
         | have to weite one thing to get the parser and the type.
        
         | outlore wrote:
         | The "type User =" statement creates a TypeScript type from the
         | zod schema, which can be useful when passing that definition
         | around to functions
         | 
         | The schema object is useful for runtime validation, e.g.
         | User.parse(). this is handy when validating payloads that come
         | over the wire that might be untrusted. the output of the
         | "parse()" function is an object of type User
         | 
         | you can kind of think of it like marshaling Json into a struct
         | in Go :)
        
         | _heimdall wrote:
         | Zod offers runtime type validation where typescript only does
         | this at build time. You can also use it for data normalization,
         | safely parsing date strings to Date objects for example.
        
         | cheriot wrote:
         | I used it to validate data from config files matched the
         | schema. I imagine it could be useful for other sources of
         | suppose-to-be-structured data like an http body.
        
         | arzig wrote:
         | There's no macro system in TS that could analyze the type to
         | build the parser. So, you work the other way and build the
         | parser and then produce the type from that.
        
         | tubthumper8 wrote:
         | > deriving a parser for it somehow
         | 
         | Serde in Rust does this with the Rust macro system, but
         | TypeScript doesn't have a macro system. That's why people have
         | to go the other way, the programmer defines the parser, then
         | TypeScript can infer the type from the parser.
         | 
         | I have seen a library that invented their own macro system (a
         | script that you configure to run before build, and it writes
         | code into your node_modules directory), though I can't recall
         | the name.
        
       | Cu3PO42 wrote:
       | Zod has been a great boon to a project I've been working on. I
       | get data from multiple sources where strong types cannot be
       | generated and checking the schema of the response has caught a
       | great number of errors early.
       | 
       | Another feature that I use intensively is transforming the
       | response to parse JSON into more complex data types, e.g. dates
       | but also project-specific types. In some situations, I also need
       | to serialize these data types back into JSON. This is where Zod
       | lacks most for my use-case. I cannot easily specify bidirectional
       | transforms, instead I need to define two schemas (one for
       | parsing, one for serializing) and only change the transforms. I
       | have added type assertions that should catch any mistakes in this
       | manual process, but it'd be great if I didn't have to keep these
       | two schemas in sync.
       | 
       | Another comment mentioned @effect/schema [0], which apparently
       | supports these encode/decode relationships. I'm excited to try it
       | out.
       | 
       | [0] https://effect.website/docs/guides/schema/introduction
        
       | n00bskoolbus wrote:
       | Something cool that I can't remember if it was posted on HN at
       | one point or I stumbled across when looking for alternatives to
       | yup but this repo has been compiling a bunch of different
       | benchmarks for runtime validation of ts validation libraries.
       | Obviously to some degree the performance is arbitrary when you're
       | reaching millions of operations per second but on the flipside
       | their benchmarks are against rather data. Would be interested to
       | see comparison of either more nested data or otherwise complex.
       | Maybe something to look at in my spare time.
       | 
       | https://moltar.github.io/typescript-runtime-type-benchmarks/
        
       ___________________________________________________________________
       (page generated 2024-10-09 23:00 UTC)