gristlabs / ts-interface-checker

Runtime library to validate data against TypeScript interfaces.
Apache License 2.0
323 stars 18 forks source link

[Feature] ability to exclude types from builder #37

Closed mdesousa closed 3 years ago

mdesousa commented 3 years ago

Right now if I define an unsupported Type or Interface in a file (e.g. generics or index types) the builder throws an error. As a work-around you can move those types to a separate file that is not processed by the builder... but makes it hard to keep the code organized and can introduce dependency smells.

It would be nice to be able to exclude specific types with a decorator:

@tiBuilderExclude
type MyGeneric<T> = { data: T };
dsagal commented 3 years ago

There are command-line options to ignore such unsupported types:

  -g, --ignore-generics         Ignores generics
  -i, --ignore-index-signature  Ignores index signature
mdesousa commented 3 years ago

Great, thanks.

exilent-ashish commented 3 years ago

nothing happening with --ignore-generics, after the compilation "T" is assigned as type of field and in runtime error throwing unknown type T

i am using the command like npm bin/ts-interface-builder message.interface.ts -o ./src/main/ --inline-imports -g

dsagal commented 3 years ago

The option --ignore-generics allows ts-interface-builder to succeed and produce some reasonable output describing the types. There is still no support for generics though. So you can limit yourself to what's supported, or add some workarounds.

For example, let's say the original file is:

export interface Bar<T> {
  bar: T;
}
export interface Foo {
  type: string;
  bar: Bar<number>;
}

The output of ts-interface-builder (with -g or --ignore-generics) has code like this:


export const Bar = t.iface([], {
  "bar": "T",
});

export const Foo = t.iface([], {
  "type": "string",
  "bar": "any",
});

const exportedTypeSuite: t.ITypeSuite = {
  Bar,
  Foo,
};
export default exportedTypeSuite;

You can use just the type Foo (not helpful for bar but helpful for fields of supported types) like so:

t.createCheckers({Foo: exportedTypeSuite.Foo});

You can use the type Bar if you tell ts-interface-checker what the type T is, for example:

t.createCheckers({...exportedTypeSuite, T: basicTypes.number});

Of course it would be fantastic to just add proper support for generics. With good understanding of tsc internals, it should be possible, but lacking it, digging out what's needed from tsc source code has led to a bunch of dead ends, and proven too time-consuming :/