Last active
February 1, 2019 18:24
-
-
Save bessgeor/41c4c4d0a2212794f95a2cc5f0962145 to your computer and use it in GitHub Desktop.
Typescript compile-time codgen reflection validator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Жесть ты решил упороться =)