Pipe: Operator Composition
pipe is the base function that takes a method and zero or more functional operators, returning a pipeline function that preserves the types of receiver, arguments, and return.
Syntax
Section titled “Syntax”import { pipe } from 'annotations-design-patterns/pipe';
const pipeline = pipe<Receiver, readonly [Arg1, Arg2], Return>( function methodOrPipeline(this: Receiver, arg1: Arg1, arg2: Arg2): Return | Promise<Return> { // your logic }, operator1<Receiver, readonly [Arg1, Arg2], Return>(...), operator2<Receiver, readonly [Arg1, Arg2], Return>(...),);Important: all operators in the same pipeline must have the same generics — the receiver, arguments tuple, and return type cannot change between operators.
Example: resilience stack
Section titled “Example: resilience stack”const safeFetch = pipe<object, readonly [url: string], Promise<Response>>( async function (this: object, url: string): Promise<Response> { return fetch(url); }, timeout<object, readonly [url: string], Promise<Response>>(5000), retry<object, readonly [url: string], Promise<Response>>({ attempts: 3 }), fallback<object, readonly [url: string], Promise<Response>>( new Response('{}', { status: 503 }) ),);
// Use itawait safeFetch.call({}, 'https://api.example.com/data');Operator order: outside to inside
Section titled “Operator order: outside to inside”The first operator in the list is the outermost. Execution flows:
- External call → first operator (outermost)
- → second operator
- → … more operators …
- → base method (innermost)
- ← response
In the example above:
timeoutis the outermost (detects slow operations)retryretries after timeoutfallbackreturns a default value if everything fails- The
fetchmethod is the innermost
Preserves synchrony when possible
Section titled “Preserves synchrony when possible”If all operators and the base method are synchronous, the pipeline returns synchronously:
const compute = pipe<object, readonly [n: number], number>( function (n: number) { return n * 2; }, fallback<object, readonly [n: number], number>(0),);
// Returns number, not Promiseconst result = compute.call({}, 5); // 10If any operator or method is async, the pipeline returns a Promise.
Invocation
Section titled “Invocation”The returned pipeline is invoked as a normal function, with .call(receiver, ...args):
const result = await pipeline.call(receiver, arg1, arg2);For invoking with typed arguments and integrated observability context, use run.
For composition details
Section titled “For composition details”See the Pipe Reference.

