gcanti / io-ts

Runtime type system for IO decoding/encoding

Home Page:https://gcanti.github.io/io-ts/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Flow, TypeScript, tcomb...

gcanti opened this issue · comments

Previous discussion: gcanti/tcomb-form#377 (comment)

@eteeselink

what's your motivation for moving from flow to ts?

There's plenty of reasons (I should write down a list..), maturity over all.

Do you consider it the spiritual successor to tcomb?

Yes and no, io-ts has a narrowed scope and wants to align with the TypeScript type system at the cost of possibly sacrifice some feature

I'm only sad that I can't use typescript class or interface syntax with it

Not sure I'm following

What's the point of runtime type checking inside a 100% typescript project

Mainly for IO validation but there are 4 use cases I'm interesting in

  • IO validation
  • runtime type introspection (which makes possible something like tcomb-form)
  • "static types extraction"
  • refinements

An example (POC) https://github.com/gcanti/prop-types-ts. There you get static AND runtime safety (so you please both TypeScript and non TypeScript users) with a single schema definition

Mainly for IO validation...

I'd say this one might not be super clear for non-fp reader.

This basically means that you can validate data received from your API. It still makes sense in pure TypeScript project because JSON.parse do not respect whatever you defined in your types. If you defined something as string it could be null or array.

Ahyes, good idea, I see the point with IO validation (and thanks @gyzerok for the clarification!)

What I meant by "I'm only sad that I can't use typescript class or interface syntax with it" was that I prefer this:

interface Person {
  name: string,
  age: number

}

over this:

const Person = t.object({
  name: t.string,
  age: t.number
})

It's nicer to look at, plus I have lots of interfaces all over the code already. But I see that it's impossible to generate the second from the first without an additional generator plugged into typescript (and tsc is notorious for not being awfully pluggable).

@eteeselink you can still use it.

interface Person {
  name: string,
  age: number
}

const personValidator = t.object({
  name: t.string,
  age: t.number
})

t.validate<Person>({}, personValidator);

The idea is just to make it a bit more convenient, because otherwise you need to write almost same thing twice.

Sure, but with that I duplicated code. I love that the compiler will fail if i duplicate the code wrong; it's really an improvement over tcomb for us in that regard, but it's still duplication.

So my point is that I wish I could summarize lines 6-10 of your example into

const personValidator = t.fromType<Person>();

You see? :-)

@eteeselink well, not sure, but I guess it's impossible to implement API in a way you want it. Do you have any implementation in mind?

@eteeselink I tried the path static type -> runtime type in the past with https://github.com/gcanti/babel-plugin-tcomb and it didn't end well (many unhandled corner cases... Some opinions here gcanti/flow-io#10 (comment)). I hope that with the other way around we can have more luck (first results are encouraging).

@gcanti wow, good read! this stuff goes a lot deeper than i expected :-)

@gyzerok no i don't think it's possible without additional generators, and gcanti got rather far in convicing me we shouldn't do it anyway.

the static type extraction from io-ts is very cool!

i don't have more genius insights ready currently, and this is a pretty vaguely scoped issue to begin with. I'm fine if you close it now :-)

Yeah, let's close the issue for now and better start with the new one if something appears on the table :)