gristlabs / ts-interface-builder

Compile TypeScript interfaces into a description that allows runtime validation
Apache License 2.0
132 stars 28 forks source link

Any plans to implement generics or typescript utilities? #19

Open dwjohnston opened 4 years ago

dwjohnston commented 4 years ago

I'm wanting to do something like this:

interface Foo {
    id: string; 
    biz: string; 
    bar: string; 
}

type PartialFoo = Pick<Foo, "id" | "biz">; 

Pretty simple.

But the compiler will give me:

Error: Generics are not yet supported by ts-interface-builder:

Is there any plan to incorporate this support?

dwjohnston commented 4 years ago

Hmmm, looking at the code, it looks like it might be easy enough to support some of the basic utility types. If I get some time, I'll see if I can do it.

https://github.com/gristlabs/ts-interface-builder/blob/9ac5de2f2b2e9cf556372c54df74913291036c28/lib/index.ts#L132

dsagal commented 4 years ago

Implementing specific generics like Pick seems reasonably straightforward. Implementing generics generally (or even just mapped types generally) is probably doable too, but requires a much deeper understanding of typescript internals.

xzilja commented 3 years ago

I'd like to try and implement support for few generic types that I am using i.e. Pick Omit Partial NonNullable and so on. Could you briefly explain where / how this should be done so I can give it a go?

dsagal commented 3 years ago

There are two generic types handled: Array<T> and Promise<T> (the latter is just treated as T, which happens to be helpful for some cases). See _compileTypeReferenceNode method. That's where the processing would start, I imagine.

As for how to process it, it would be nice to do something that could extend to generics more generally later. E.g. translate Pick<T> maybe to t.instance('Pick', 'T'), and add support on ts-interface-checker side, which recognizes a few names of generics, looks up the type object for the type argument(s), and does something custom to turn those type objects into new ones.