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

如何在TypeScript函数式管道中通过高阶转换器自动推断类型?

问题:让TypeScript自动推断pipe中merge函数的泛型类型

需求背景

我正在构建一个模拟器,使用fp-ts的pipe让对象通过多个函数逐步转换。为提升代码表现力,我采用高阶函数创建转换器,期望代码能写成如下形式:

pipe(
    { name: "Nick" }, 
    merge({ age: 34 }), 
    merge({ job: "programmer" }), 
    merge({ married: true })
);

理想状态下,通过为pipe指定类型实现类型安全,示例如下:

type Guy = { name: string };
type GuyWithAge = Guy & { age: number };
type GuyWithAgeAndJob = GuyWithAge & { job: string };
type GuyWithAgeAndJobAndMarried = GuyWithAgeAndJob & { married: boolean };

pipe<Guy, GuyWithAge, GuyWithAgeAndJob, GuyWithAgeAndJobAndMarried>(
    { name: "Nick" },
    merge({ age: 34 }), 
    merge({ job: "programmer" }), 
    merge({ married: true })
);

// 最终结果: { name: "Nick", age: 34, job: "programmer", married: true }

我希望TypeScript能自动推断每一步的类型,仅接受类型间的差异,确保对象转换的类型安全。

当前实现与问题

我已通过泛型和TypeScript工具类型实现核心功能,但存在冗余问题:每次调用merge时都需要显式指定泛型类型。代码如下:

// Merge 类似 A & B,但会用B的属性覆盖A的同名属性,等同于 {...A, ...B}
type Merge<First extends object, Second extends object> = Omit<
  First,
  keyof Second
> &
  Second;

// Delta 是与 From 合并后得到 To 的对象类型
export type Delta<From extends object, To extends object> = {
  [K in keyof To as K extends keyof From
    ? To[K] extends From[K]
      ? never
      : K
    : K]: To[K];
};

const merge =
  <First extends object, Second extends object>(
    delta: Delta<First, Second>,
  ) =>
  (obj: First): Merge<First, Delta<First, Second>> => {
    const merged = {
      ...obj,
      ...delta,
    };
    return merged;
  };

type Guy = { name: string };
type GuyWithAge = Guy & { age: number };
type GuyWithAgeAndJob = GuyWithAge & { job: string };
type GuyWithAgeAndJobAndMarried = GuyWithAgeAndJob & { married: boolean };

const guy = pipe<Guy, GuyWithAge, GuyWithAgeAndJob, GuyWithAgeAndJobAndMarried>(
  { name: "Nick" },
  merge<Guy, GuyWithAge>({ age: 34 }),
  merge<GuyWithAge, GuyWithAgeAndJob>({ job: "programmer" }),
  merge<GuyWithAgeAndJob, GuyWithAgeAndJobAndMarried>({ married: true })
);

我的问题是:有没有办法让TypeScript自动推断pipe中每个merge调用的正确泛型,从而无需手动指定类型?

补充分析

我进一步拆解了问题:pipe期望接收A => B类型的函数。当传入merge<First, Second>(delta)时,它返回(obj: First) => Merge<First, Delta<First, Second>>。

也就是说,我向pipe提供的函数类型是(obj: First) => Merge<First, Delta<First, Second>>,而pipe需要的是A => B,理论上A应映射到First,B应映射到Merge<First, Delta<First, Second>>(理想情况下可简化为Second,但不确定该简化是否正确)。

我想理解为何TypeScript无法自动推断A对应First、B对应Second,以及如何修复代码以实现预期的自动推断。

内容的提问来源于stack exchange,提问作者Nick Manning

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:43:15