Promise
The promise category handles code paths where a value may be synchronous or asynchronous,
and provides small type-level helpers around Promise.
MaybePromise
Section titled “MaybePromise”type MaybePromise<T> = T | Promise<T>The type of a value that may or may not be a promise.
import type { MaybePromise } from 'type-plus'
function load(): MaybePromise<string> { return cache ?? fetchValue()}transformMaybePromise
Section titled “transformMaybePromise”function transformMaybePromise<T, R>(value: Promise<T>, transformer: (value: T) => R): Promise<R>function transformMaybePromise<T, R>( value: T, transformer: (value: T) => R,): T extends Promise<any> ? Promise<R> : RApplies transformer to the value, or to the resolved value when it is a promise.
The return type follows the input: a promise in, a promise out; a plain value in, a plain value out.
import { transformMaybePromise } from 'type-plus'
const a = transformMaybePromise(1, (v) => v + 1) // 2, typed numberconst b = transformMaybePromise(Promise.resolve(1), (v) => v + 1) // Promise<number>The same function is also reachable as MaybePromise.transform, a const that shares the name of the type:
import { MaybePromise } from 'type-plus'
const r = MaybePromise.transform(1, (v) => `${v}`) // '1', typed stringThis is what lets a single code path stay synchronous when it can, without wrapping every value in a promise.
isPromise
Section titled “isPromise”function isPromise<R = any>(subject: unknown): subject is Promise<R>A type guard that checks for a thenable.
import { isPromise } from 'type-plus'
function unwrap(value: MaybePromise<number>) { return isPromise(value) ? value.then((v) => v * 2) : value * 2}mapSeries
Section titled “mapSeries”function mapSeries<R, T = any>(values: T[], fn: (value: T) => Promise<R>): Promise<R[]>Maps over an array with an async function, one at a time, in order.
Unlike Promise.all(values.map(fn)), the next call does not start until the previous one resolves.
import { mapSeries } from 'type-plus'
const ids = ['a', 'b', 'c']const results = await mapSeries(ids, (id) => fetchRecord(id)) // Record[]Use it when the calls must not run concurrently — rate limits, ordered writes, shared resources.
AwaitedProp
Section titled “AwaitedProp”type AwaitedProp<T extends AnyRecord, K extends keyof T>⚗️ transform — awaits only the selected properties of a record, leaving the rest unchanged.
import type { AwaitedProp } from 'type-plus'
type Input = { id: number; data: Promise<string>; meta: Promise<object> }
type R = AwaitedProp<Input, 'data'> // { id: number; data: string; meta: Promise<object> }PromiseValueMerge
Section titled “PromiseValueMerge”type PromiseValueMerge<P1, P2, P3 = any, ..., P9 = any>⚗️ transform — a promise of the intersection of the awaited values of up to nine promises.
import type { PromiseValueMerge } from 'type-plus'
type R = PromiseValueMerge<Promise<{ a: 1 }>, Promise<{ b: 2 }>> // Promise<{ a: 1 } & { b: 2 }>It describes the result of merging several concurrent fetches into one object.
PromiseValue
Section titled “PromiseValue”type PromiseValue<P extends Promise<any>>Extracts the value type from a promise.
type R = PromiseValue<Promise<string>> // string