Last active
August 19, 2019 23:42
-
-
Save SamirTalwar/b4553a0374c4d5d516f98f88aaaf81a2 to your computer and use it in GitHub Desktop.
Random hacks you can do with TypeScript.
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 Status = "passed" | "failed" | "error" | "unknown"; | |
| interface Things { | |
| a: string; | |
| b: number; | |
| c: { | |
| d: { | |
| e: string; | |
| }; | |
| f: Array<{ g: number }>; | |
| }; | |
| } | |
| // example | |
| interface PromisedThings { | |
| a: Promise<string>; | |
| b: Promise<number>; | |
| c: { | |
| d: { | |
| e: Promise<string>; | |
| }; | |
| }; | |
| } | |
| type PromiseObject<O> = { | |
| [K in keyof O]: O[K] extends object ? PromiseObject<O[K]> : Promise<O[K]> | |
| }; | |
| const foo: PromiseObject<Things> = {} as any; | |
| const a = foo.a; | |
| const e = foo.c.d.e; | |
| const g = foo.c.f[0].g; | |
| type UnpromiseObject<O> = { | |
| [K in keyof O]: O[K] extends Promise<infer V> | |
| ? V | |
| : O[K] extends PromiseObject<infer V> | |
| ? V | |
| : O[K] | |
| }; | |
| const bar: UnpromiseObject<PromiseObject<Things>> = {} as any; | |
| bar.c.d.e; | |
| /// | |
| interface State { | |
| value: number; | |
| } | |
| const state: State = {} as any; | |
| interface Actions { | |
| inc: (n: number) => number; | |
| dec: (n: number) => number; | |
| reset: () => [number, string]; | |
| somethingElse: string; | |
| } | |
| const _actions = { | |
| inc(n: number) { | |
| return state.value + n; | |
| } | |
| }; | |
| type _Actions = TransformActions<typeof _actions>; | |
| interface ActualActions { | |
| inc: (n: number) => (state: State) => Promise<number>; | |
| dec: (n: number) => (state: State) => Promise<number>; | |
| reset: () => (state: State) => Promise<[number, string]>; | |
| } | |
| type TransformActions<A> = { | |
| [K in keyof A]: ( | |
| ...args: FunctionArgs<A[K]> | |
| ) => (state: State) => Promise<FunctionResult<A[K]>> | |
| }; | |
| type FunctionArgs<F> = F extends (...args: infer Args) => any ? Args : never; | |
| type FunctionResult<F> = F extends (...args: any[]) => infer Result | |
| ? Result | |
| : never; | |
| const actions: TransformActions<Actions> = {} as any; | |
| const value: Promise<number> = actions.inc(3)(state); | |
| actions.somethingElse(); // error |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment