如何定义TypeScript的pipe函数类型以支持延迟链式调用?
实现支持链式延迟执行的TypeScript Pipe类型
完整实现代码
// 定义链式Pipe的核心类型,跟踪输入输出类型 type Pipe<I, O> = { // 接收转换函数,返回更新类型后的新Pipe then<NextO>(fn: (input: O) => NextO): Pipe<I, NextO>; // 返回最终执行函数,传入初始参数后触发所有链式函数执行 value(): (input: I) => O; }; // 初始状态的Pipe类型,输入输出类型一致 type InitialPipe<T> = Pipe<T, T>; // 实现pipe函数,创建链式调用实例 function pipe<T>(): InitialPipe<T>; function pipe(): InitialPipe<unknown>; function pipe() { const fns: Array<(input: unknown) => unknown> = []; const pipeInstance: Pipe<unknown, unknown> = { then(fn) { fns.push(fn); return pipeInstance; }, value() { return (initialInput) => fns.reduce((currentValue, fn) => fn(currentValue), initialInput); }, }; return pipeInstance as unknown as InitialPipe<unknown>; } // 辅助函数的类型定义(确保与Pipe类型兼容) function add(n: number): (x: number) => number { return (x) => x + n; } function toString<T>(value: T): string { return String(value); } function prepend(padChar: string, minLength: number): (str: string) => string { return (str) => str.padStart(minLength, padChar); }
类型设计核心要点
- 泛型类型流转:
Pipe<I, O>通过泛型I(初始输入类型)和O(当前输出类型),在每次调用then时自动更新类型——传入的转换函数接收O类型并返回NextO,因此新的Pipe类型会变为Pipe<I, NextO>,全程保证类型安全。 - 初始状态兼容:
InitialPipe<T>作为初始Pipe的类型,输入输出类型一致,pipe函数的重载支持显式指定初始类型(如pipe<number>()),或让TypeScript通过后续调用自动推断初始类型。 - 延迟执行逻辑:
pipe内部维护一个函数数组,then仅收集转换函数,不会立即执行;value()返回的函数才是真正的执行入口,传入初始参数后,通过reduce依次执行所有收集的函数,完成链式转换。
验证示例用法
// 创建链式转换函数 const getStringFromNumber = pipe<number>() .then(add(1)) .then(toString) .then(prepend('0', 5)) .value(); // 执行转换,类型自动推断为string,结果为"00006" const result = getStringFromNumber(5);
内容的提问来源于stack exchange,提问作者Artur
相关产品推荐
相关产品推荐

