UNPKG

@synstack/resolved

Version:

Type-safe piping of synchronous or asynchronous values

66 lines (64 loc) 2.7 kB
type Resolvable<T> = Promise<T> | T; declare namespace Resolvable { type Infer<T> = Awaited<T>; type IsPromise<T> = T extends Promise<any> ? true : never; type ArrayOf<T> = Array<Resolvable<T>>; namespace ArrayOf { type Infer<T> = T extends readonly any[] ? { [K in keyof T]: Resolvable.Infer<T[K]>; } : never; type HasPromise<T> = T extends readonly any[] ? { [K in keyof T]: Resolvable.IsPromise<T[K]>; }[number] : never; } type MaybeArray<T> = Resolvable.ArrayOf<T> | Resolvable<T>; namespace MaybeArray { type Infer<T> = T extends readonly any[] ? { [K in keyof T]: Resolvable.Infer<T[K]>; } : Resolvable.Infer<T>; type IsPromise<T> = T extends readonly any[] ? { [K in keyof T]: Resolvable.IsPromise<T[K]>; }[number] : Resolvable.IsPromise<T>; } } /** * Resolves all values in the array in parallel * @param value The array to resolve * @returns If the array contains promises, a promise of an array of values. Otherwise, the array. */ declare const resolveAll: <U extends readonly any[]>(value: U) => true extends Resolvable.ArrayOf.HasPromise<U> ? Promise<Resolvable.ArrayOf.Infer<U>> : U; declare class Resolver<T extends Resolvable<any>> { private readonly _value; constructor(value: T); /** * Get the value of the resolver * @returns The value or a single promise of the value * * - If the value is an array containing promises, the array will be resolved with `Promise.all` */ get $(): T extends readonly any[] ? true extends Resolvable.ArrayOf.HasPromise<T> ? Promise<Resolvable.ArrayOf.Infer<T>> : T : T; valueOf(): T; /** * Apply a function to the value * @param fn the function to apply to the value * @returns a new Resolver instance with the result of the function, either a value or a promise of a value */ _<R>(fn: (value: Resolvable.MaybeArray.Infer<T>) => R): true extends Resolvable.MaybeArray.IsPromise<T> ? true extends Resolvable.MaybeArray.IsPromise<R> ? Resolver<R> : Resolver<Promise<R>> : Resolver<R>; } /** * A piping utility which preserves the sync/async state of the value * @param value The value to pipe * @returns A new Resolver instance * * ```ts * import { pipe } from "@synstack/resolved"; * * // Sync * const value: string = pipe("Hello World")._((v) => v.toUpperCase()).$; * * // Async * const promiseValue: Promise<string> = pipe("Hello World")._((v) => Promise.resolve(v.toUpperCase())).$; * ``` */ declare const pipe: <T>(value: T) => Resolver<T>; export { Resolver as R, Resolvable as a, pipe as p, resolveAll as r };