Skip to content

Instantly share code, notes, and snippets.

@bessgeor
Last active February 1, 2019 18:24
Show Gist options
  • Save bessgeor/41c4c4d0a2212794f95a2cc5f0962145 to your computer and use it in GitHub Desktop.
Save bessgeor/41c4c4d0a2212794f95a2cc5f0962145 to your computer and use it in GitHub Desktop.
Typescript compile-time codgen reflection validator
import * as moment from 'moment';
type ArrayLike = any[] & { length: number }; // { length?: number } extends any[] == true
type IsNullable<T> = null extends T ? true : false;
type IsUndefinable<T> = undefined extends T ? true : false;
type Unwrap<T> = T extends (infer U)[] ? U : never;
type IsArray<T> = T extends ArrayLike ? true : false;
type EnumLike<T> =
IsNullable<T> extends true ? never
: IsUndefinable<T> extends true ? never
: { [F in keyof T]: number; }
;
type DefaultMap = 'ignore';
type TypeValue<T, TNullable extends boolean, TUndefinable extends boolean> =
T extends DefaultMap
? TNullable extends true
? TUndefinable extends true
? 'null | undefined'
: 'null'
: TUndefinable extends true
? 'undefined'
: DefaultMap
: T extends boolean ? 'boolean'
: T extends string ? 'string'
: T extends number ? 'number'
: T extends Date ? 'date'
: T extends moment.Moment ? 'moment'
: T extends moment.Duration ? 'moment-duration'
: T extends {} ? TypeInfo<T>
: T extends any[] ? ArrayFieldInfo<T, TNullable, TUndefinable>
: T extends EnumLike<T> ? 'number'
: DefaultMap
;
type AboutField<TNullable extends boolean, TUndefinable extends boolean, TArray extends boolean> = {
readonly isNullable: TNullable;
readonly isUndefinable: TUndefinable;
readonly isArray: TArray;
}
type Undefault<T> = T extends null | undefined ? DefaultMap : T;
type SimpleFieldInfo<T, TNullable extends boolean, TUndefinable extends boolean> =
AboutField<TNullable, TUndefinable, false>
& {
readonly type: TypeValue<T, TNullable, TUndefinable>;
}
;
type ArrayFieldInfo<T, TNullable extends boolean, TUndefinable extends boolean> =
AboutField<TNullable, TUndefinable, true>
& {
item: RawField<Unwrap<T>>
}
;
type FieldInfo<T, TNullable extends boolean, TUndefinable extends boolean> =
true extends IsArray<T>
? ArrayFieldInfo<T, TNullable, TUndefinable>
: SimpleFieldInfo<T, TNullable, TUndefinable>
;
type RawField<T> = FieldInfo<Undefault<T>, IsNullable<T>, IsUndefinable<T>>;
export type TypeInfo<T extends {}> = {
readonly [F in keyof T]: RawField<T[F]>
}
@Swistikkk
Copy link

Жесть ты решил упороться =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment