Last active
March 7, 2019 11:33
-
-
Save cevek/f3823ace147d642a0c04c2bc9e153837 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
type AtLeastOne<T, U = { [K in keyof T]: { [P in K]: T[P] } }> = { [P in keyof T]?: T[P] } & U[keyof U]; | |
type Exactify<Base, T extends Base> = Base & { [K in keyof T]: K extends keyof Base ? T[K] : never }; | |
declare function requireExact<X extends Exactify<{a: number}, X>>(x: X): void; | |
type Omit<T, Keys extends string> = Pick<T, Exclude<keyof T, Keys>>; | |
type IfEquals<X, Y, A=X, B=never> = | |
(<T>() => T extends X ? 1 : 2) extends | |
(<T>() => T extends Y ? 1 : 2) ? A : B; | |
type WritableKeys<T> = { | |
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P> | |
}[keyof T]; | |
type ReadonlyKeys<T> = { | |
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, never, P> | |
}[keyof T]; | |
type DateMutableMethods = | |
| 'setTime' | |
| 'setMilliseconds' | |
| 'setUTCMilliseconds' | |
| 'setSeconds' | |
| 'setUTCSeconds' | |
| 'setMinutes' | |
| 'setUTCMinutes' | |
| 'setHours' | |
| 'setUTCHours' | |
| 'setDate' | |
| 'setUTCDate' | |
| 'setMonth' | |
| 'setUTCMonth' | |
| 'setFullYear' | |
| 'setUTCFullYear'; | |
type RDate = { [P in Exclude<keyof Date, DateMutableMethods>]: Date[P] }; | |
interface RArray<T> extends ReadonlyArray<R<T>> {} | |
interface RMap<K, V> extends ReadonlyMap<R<K>, R<V>> {} | |
interface RSet<V> extends ReadonlySet<R<V>> {} | |
interface PPromise<T> extends Promise<R<T>> {} | |
type Mutable<T> = Mut<T> & T | T; | |
type Mut<T> = { __brand: Mut<T>; value: T }; | |
type R<T> = T extends Array<infer R> | |
? RArray<R> | |
: T extends Map<infer K, infer V> | |
? RMap<K, V> | |
: T extends Set<infer V> | |
? RSet<V> | |
: T extends Date | |
? RDate | |
: T extends Promise<infer P> | |
? PPromise<P> | |
: T extends EventTarget | |
? T | |
: T extends Error | |
? T | |
: T extends Mut<infer R> | |
? R | |
: T extends (...args: infer Arg) => infer Ret | |
? (...args: Arg) => R<Ret> | |
: T extends object ? { readonly [P in keyof T]: R<T[P]> } : T; | |
type RetType<T> = T extends (...args: any[]) => infer R ? R : any; | |
type Args<T> = T extends (...args: infer A) => infer R ? A : any; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment