You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义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);
}

类型设计核心要点

  1. 泛型类型流转:Pipe<I, O>通过泛型I(初始输入类型)和O(当前输出类型),在每次调用then时自动更新类型——传入的转换函数接收O类型并返回NextO,因此新的Pipe类型会变为Pipe<I, NextO>,全程保证类型安全。
  2. 初始状态兼容:InitialPipe<T>作为初始Pipe的类型,输入输出类型一致,pipe函数的重载支持显式指定初始类型(如pipe<number>()),或让TypeScript通过后续调用自动推断初始类型。
  3. 延迟执行逻辑: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:20:32