Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript version #254

Closed
steida opened this issue Apr 1, 2020 · 4 comments
Closed

TypeScript version #254

steida opened this issue Apr 1, 2020 · 4 comments

Comments

@steida
Copy link

steida commented Apr 1, 2020

Upcoming TypeScript version is a chance to do things right. Sure we can have typed API with TypeScript compiler checking the right composition, that's standard, but we should be able to enforce types even for runtime. Fauna is awesome but as any document DB, any shape approach can accidentally harm the developer. In the end, we need types. But can we blindly believe that our database will return what we expect? Never. Any serious application needs to validate/parse values out of the application boundary. Period.

That's why https://github.com/gcanti/io-ts is such an awesome library. Mature, well-tested, well-designed.

I highly recommend to check it and use it for development TypeScript version of faunadb driver.

For example, this is the FaunaID type I am using. And I will need FaunaRef generic type. And types for Fauna errors. Etc.

interface FaunaIDBrand {
  readonly FaunaID: unique symbol;
}
export const FaunaID = t.brand(
  t.string,
  (s): s is t.Branded<string, FaunaIDBrand> => /^\d+$/.test(s),
  'FaunaID',
);
export type FaunaID = t.TypeOf<typeof FaunaID>;

I would love to help with any issue regarding TypeScript version design.

@steida
Copy link
Author

steida commented Apr 1, 2020

Another example. Note serializeCookie signature requires FaunaSecret type. It can not accept a plain string. t.type({ secret: FaunaSecret }) ensures via its decode method that we really got secret.

Screenshot 2020-04-01 at 22 11 18

Maybe this stuff (Either and algebraic types composition and functional domain modeling) is new for you. It's much easier than it looks. And super useful. And available in TypeScript.

I highly recommend the first five minutes of this talk: https://www.youtube.com/watch?v=PLFl95c-IiU

@hasparus
Copy link

hasparus commented Apr 1, 2020

I'll just leave a note here.

I am aware that io-ts and fp-ts flavor functional API might not be for everyone.
I believe the idea of parsing data on application boundary to be sound regardless of preferred paradigm.

ts-json-validator is a nice alternative.

I'm using io-ts, but I wanted to present you with another option.

Pros

  1. It uses ajv, so it's crazy fast.
    image
  2. JSON Schema is pretty standard and the API might be more familar to some people.

Cons

There's a trade-off. It has 10x less stars and the API is subject to change.


The attached chart is from this benchmark.

@steida
Copy link
Author

steida commented Apr 1, 2020

The performance of io-ts is a non-issue. And nobody is supposed to be forced to use it. It's about how types should be defined. io-ts first ensures we can have reliable runtime-type checking for people who needs it. With Either. Performance micro-optimization is orthogonal.

Note this can be easily ensured by io-ts. That's the point. Check https://www.youtube.com/watch?v=PLFl95c-IiU

Screenshot 2020-04-01 at 23 35 01

@hasparus
Copy link

hasparus commented Apr 2, 2020

I've been using io-ts for over a year, you don't have to advertise it to me :D

Note this can be easily ensured by io-ts.

This is checked by ts-json-validator at runtime.
"Can't enforce using type system" means "statically typechecked with type inferred from decoder".

All validating for refinement types must be done in userland at runtime unless there's been some recent development in RSC.

ts-json-validator currently supports every keyword, though not all of them contribute to the final derived type.

All good decoder libraries do two things.

  1. Validate
  2. Derive a static type

The table you attached is about deriving.

JSON Schema can do a lot, but it isn't turing complete.
There are certainly many use cases, which call for defining(refining) your types with predicates,
what I believe is impossible in ts-json-validator.

Check https://www.youtube.com/watch?v=PLFl95c-IiU

I watched this talk from NDC Sydney 2017. I really liked it :)
Did the 2019 version change a lot?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants