Skip to content

Instantly share code, notes, and snippets.

@cefn
Created December 20, 2023 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cefn/93a560b84087f9bf5d53df647ce4f356 to your computer and use it in GitHub Desktop.
Save cefn/93a560b84087f9bf5d53df647ce4f356 to your computer and use it in GitHub Desktop.
Create a synchronous structure from a lookup of promises
/** Stricter keyof */
export type RecordKey<T> = T extends Partial<infer R> ? (R extends Record<infer K, unknown> ? K : never) : never;
/** Stricter type for members of Object.entries(t) */
export type RecordEntry<T> = { [K in RecordKey<T>]: [K, Required<T>[K]] }[RecordKey<T>];
/** Type-narrowed equivalent of Object.entries */
export function entries<T extends Readonly<NonNullable<{}>>>(obj: T) {
return Object.entries(obj) as RecordEntry<T>[];
}
/** Type-narrowed equivalent of Object.fromEntries */
export function fromEntries<const T extends ReadonlyArray<readonly [PropertyKey, unknown]>>(entries: T) {
return Object.fromEntries(entries) as { [K in T[number] as K[0]]: K[1] };
}
/** Given a lookup of (async) FragmentResult Promises, creates an eventual lookup of the settlements of those promises
* which can be interrogated without await.
*/
async function populateFragmentSettlementLookup<const L extends Record<PropertyKey, Promise<FragmentResult>>>(
promiseLookup: L,
) {
return fromEntries(
await Promise.all(
entries(promiseLookup).map(([key, promise]) =>
promise
.then((value: FragmentResult) => [key, { status: 'fulfilled', value }] as const)
.catch((reason: unknown) => [key, { status: 'rejected', reason }] as const),
),
),
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment