Live data from Hacker News

Designing the perfect TypeScript schema validation library

vriad.com

71–77 of 77 posts

Re: Designing the perfect TypeScript schema validation library

#71
post #69

Earlier quoted context omitted.

Sure, this discussion is full of options, but none are really perfect, so there are plenty of opportunities for bikeshedding!

I guess you could call trying to offer a helpful suggestion bike shedding ¯\_(ツ)_/¯

Excuse me if I have offended you, my intent was rather far from that.

The bike-shedding is to which one to pick right now, when there doesn't seem to be a clear superior choice.

I saw your suggestion as just as a bit half-baked as the ad-hoc stuff I actually use now, and the other in-chimings in the discussion. (io-ts, utility-types, runtypes, etc. all are great, but as the title indicates it feels there should be one schema system specifically designed for TS. That can be used for description and validation of all interfaces of a TS system, including incoming requests, static and runtime configuration, outgoing data, and mapping these to internal domain modeling.)

Re: Designing the perfect TypeScript schema validation library

#72
post #71

Earlier quoted context omitted.

I guess you could call trying to offer a helpful suggestion bike shedding ¯\_(ツ)_/¯

Excuse me if I have offended you, my intent was rather far from that. The bike-shedding is to which one to pick right now, when there doesn't seem to be a clear superior choice. I saw your suggestion as just as a bit half-baked as the ad-hoc stuff I actually use now, and the other in-chimings in the discussion. (io-ts, utility-types, runtypes, etc. all are great, but as the title indicates it feels there should be on…

> Excuse me if I have offended you, my intent was rather far from that. > > The bike-shedding is to which one to pick right now, when there doesn't seem to be a clear superior choice.

Fair enough. My intent was not bike shedding, but just mentioning a thing that exists if you would like to use it. In my experience most people are not aware `config` supports TypeScript config files.

> I saw your suggestion as just as a bit half-baked as the ad-hoc stuff I actually use now, and the other in-chimings in the discussion.

For what it's worth, for libraries which require config I combine io-ts (well my wrapper around it) for validation and the types it generates for type safety. It is not an experience that feels half-baked to me. It guarantees that clients using my libraries provide valid configuration at runtime, and allows them to get static guarantees of the same (which I also employ in clients which use those libraries).

> (io-ts, utility-types, runtypes, etc. all are great, but as the title indicates it feels there should be one schema system specifically designed for TS. That can be used for description and validation of all interfaces of a TS system, including incoming requests, static and runtime configuration, outgoing data, and mapping these to internal domain modeling.)

IMO there doesn't need to be just one, as long as people can find one that suits their needs. I certainly use io-ts for all of the things you describe, it is designed specifically for TS, and I am quite happy with it.

Re: Designing the perfect TypeScript schema validation library

#73

Earlier quoted context omitted.

It's explicitly one of the language's non-goals[1]. > Add or rely on run-time type information in programs, or emit different code based on the results of the type system. Instead, encourage programming patterns that do not require run-time metadata. [1] https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...

I understand it (there's already enough to do at type level that runtime level is a non-goal), but types are purely indicative at IO boundaries. Validation still needs to happen

That's right. So since it won't be a part of the language, libraries like this are being developed.

Re: Designing the perfect TypeScript schema validation library

#74
post #68

Earlier quoted context omitted.

See, I take the opposite view: consider that the 'model' is the abstract structure of the data which your application knows about. In your case, contact info is a piece of related data that your application knows about, can traverse to, parse, and consume, and it can be either present or absent. To me, `null` fits that case perfectly (personally I'd use Maybe, but, same idea). Finally, in cases where you're modeling…

What is `dict()`? What's the meaning of `null`? `undefined` literally means the value is not defined. `null` only has a technical meaning, which says its value is the null pointer.

That's not what null means in javascript and typescript. There, it's more like 'null' signals that there is no value, and 'undefined' signals that there is no variable.

Re: Designing the perfect TypeScript schema validation library

#75
post #68

Earlier quoted context omitted.

What is `dict()`? What's the meaning of `null`? `undefined` literally means the value is not defined. `null` only has a technical meaning, which says its value is the null pointer.

That's not what null means in javascript and typescript. There, it's more like 'null' signals that there is no value, and 'undefined' signals that there is no variable.

All runtime differences are quite neglectable if you use typescript, at least in my experience. You never accidentally use unassigned variables in typescript. Also, `{ x: undefined }` and `{}` are distinguishable.

Undefined plays well together with optional fields in typescript, null does not and requries normalization! `undefined` in a JSON array is a problem though.

Re: Designing the perfect TypeScript schema validation library

#76
post #33

I built something like this a few months ago but struggled to explain to almost everyone except die hard TypeScript fans what the big deal was. I explained it was all about the type inference from the schema so I could make guarantees across runtime boundaries. This is what I came up with, though this library looks like it may be more comprehensive than what I wrote. Struggled to come up with a good name to represent…

I guess it's something in the air! Given the popularity of the other libraries, it's surprising that there's isn't an optimal one. And yeah, unless you've gone down the rabbit hole of type safety obsession, it's hard to understand the necessity of this. I like that you specifically call out REST API validation in your docs...the difficultly of type safe API implementation was what drove me to build zod. I'm using Zod…

I think it sounds super interesting, would love to see how you've solved it :)

Re: Designing the perfect TypeScript schema validation library

#77

While I think this is pretty cool, given his use case (wanting to use a strongly typed client and server), I can't see why one wouldn't just use GraphQL with TypeScript on both the client and server. I've done this and I love it: 1. Define the GraphQL interface with GraphQL's typedef language. GraphQL then takes care of validating all the request and responses at runtime. 2. Use something like https://github.com/dota…

Been meaning to respond to this properly.

I tried this exact approach initially but gave up after experiencing a series of frustrations.

1. I'm operating in a highly-connected, relation-heavy data domain (medical) where the queries I needed to do required a LOT of joins. I wasn't good enough at SQL to make the queries performant in my resolvers. I ended up switching to Neo4j and all the performance problems went away. Unfortunately Neo4j doesn't enforce ANY field level schema whatsoever Zod provides the type enforcement for the whole data layer. I

2. I had a lot of trouble getting the codegen pipelines to work properly, and I got really sick of using codegen to create types for my queries. I also just don't like defining my queries as strings in the first place. There were scenarios where I would run slightly different variants of a query depending on some conditional logic and I had to define these queries separately. I'd much prefer to use a client-side query builder that can be used in conjunction with conditional logic but I couldn't find something to that effect (this was 15 months ago, perhaps things are different now).

3. This is far dumber but I've enjoyed building my own schema definition tooling so I can include whatever metadata on my types without needing to split up my definitions in one place. For instance, on every property of a given model, I'm able to include a name (e.g. "First name") that I can use to auto-generate forms and the like. With GraphQL I would define the model properties in GQL and the other metadata in a separate file. Again, it's dumb but it's a preference I have.

4. I don't like that you have to define relations on both sides in GQL. I'd rather "register" a bi-directional "edge" in one place, instead of splitting it into its two unidirectional "components". Again, just a (rather nitpicky) personal preference. I'm building some schema definition and querying tooling on top of Zod to this effect.

5. Typing the mutations was a huge PITA. Many mutation parameters are a slightly modified version of an already-defined type (e.g., a `createUser` mutation will accept a User instance but without the `id` property). But because all the definitions are in GQL, there isn't an easy way to represent this without highly duplicative typings, like this from the GraphQL docs:

  input MessageInput {
    content: String
    author: String
  }

  type Message {
    id: ID!
    content: String
    author: String
  }

  type Mutation {
    createMessage(input: MessageInput): Message
    updateMessage(id: ID!, input: MessageInput): Message
  }
I'm planning to look back into this given the upcoming release of Prisma 2 and the maturation of prisma-nexus, which I think solve some of these complaints.
Post reply on HN