Created
March 3, 2023 18:51
-
-
Save DScheglov/b6c4021e2d12cbd590f1ae3b26504167 to your computer and use it in GitHub Desktop.
propsResolver
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
type AnyResolvers = { | |
[prop in PropertyKey]: (params: any) => any | |
} | |
type Resolved<R extends AnyResolvers> = { | |
[prop in keyof R]: Awaited<ReturnType<R[prop]>> | |
} | |
type UnionToIntersection<U> = (U extends any ? (a: U) => any : never) extends ((b: infer A) => any) ? A : never; | |
type Params<R extends AnyResolvers> = UnionToIntersection<{ | |
[prop in keyof R]: Parameters<R[prop]> extends [] ? {} : Parameters<R[prop]>[0] | |
}[keyof R]> | |
const allNames = <T extends {}>(obj: T) => [ | |
...Object.getOwnPropertyNames(obj) , | |
...Object.getOwnPropertySymbols(obj), | |
] as Array<keyof T>; | |
const isPromise = (value: any): value is Promise<unknown> => typeof value?.then === "function"; | |
const then: { | |
<T, R>(value: T, callback: (v: T) => R): R; | |
<T, R>(value: Promise<T>, callback: (v: T) => R): Promise<Awaited<R>> | |
} = <T, R>( | |
value: T | Promise<T>, | |
callback: (v: T) => R, | |
) => isPromise(value) ? value.then(callback) : callback(value); | |
const propsResolver = <R extends AnyResolvers>(resolvers: R) => | |
(params: Params<R>): Promise<Resolved<R>> => { | |
const result = {} as Resolved<R>; | |
return Promise.all(allNames(resolvers).map( | |
prop => then( | |
resolvers[prop](params), | |
propResult => { result[prop] = propResult; } | |
) | |
)).then(() => result) | |
} | |
/// ======= Usage ======= | |
const getData = propsResolver({ | |
x: ({ xId }: { xId: number }) => Promise.resolve(xId), | |
y: ({ yId }: { yId: string }) => Promise.resolve(yId), | |
z: () => 1 as const, | |
}); | |
async function main() { | |
const value = await getData({ xId: 1, yId: "2" }); | |
console.log(value); | |
type T = { | |
[p in keyof typeof value]: (typeof value)[p] | |
} | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment