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

如何修正TypeScript代理构建器中build方法的返回类型问题?

问题:构建器build方法返回错误类型,无法返回完整目标类型

我需要实现一个类型构建器,能在构建过程中隐藏指定属性(防止用户修改预设值),目前用代理方案实现后,构建器的build()方法无法返回正确的完整类型——比如预设了type: 'basic'的basicUserBuilder,调用build()后应该返回User类型,但实际返回的是Omit<User, 'type'>。

原代码示例

type ProxyBuilder<Type, SubType = Type> = {
  [Key in keyof SubType]: (arg: SubType[Key]) => ProxyBuilder<SubType>;
} & { build(): Type }; // 此处Type被后续类型覆盖

function proxyBuilder<Type, SubType = Type>(
  defaultValues?: Partial<Type>
): ProxyBuilder<Type, SubType> {
  const built: any = { ...defaultValues };
  const builder = new Proxy(
    {},
    {
      get: function (_target, prop) {
        if (prop === 'build') return () => built as Type;

        return (value: any) => {
          built[prop] = value;

          return builder as SubType;
        };
      },
    }
  );

  return builder as any;
}

type User = {
  type: 'admin' | 'basic';
  name: string;
  age: number;
};

const basicUserBuilder = () =>
  proxyBuilder<User, Omit<User, 'type'>>({ type: 'basic' });

const jane = basicUserBuilder()
  .type('admin') // 此处希望触发类型错误(隐藏属性)
  .name('Jane')
  .age(42)
  .build(); // 返回类型为Omit<User, 'type'>,不符合预期

问题原因

原代码中,每次调用构建器的属性方法后,返回的类型被断言为SubType,导致构建器的泛型Type被替换成了SubType,最终build()的返回类型被覆盖为SubType而非原始的Type。

解决方案

调整泛型传递逻辑,让构建器始终保留原始目标类型Type,仅用SubType控制可调用的属性:

type ProxyBuilder<Type, SubType = Type> = {
  // 属性方法返回的构建器仍保留原始Type泛型
  [Key in keyof SubType]: (arg: SubType[Key]) => ProxyBuilder<Type, SubType>;
} & { build(): Type };

function proxyBuilder<Type, SubType = Type>(
  defaultValues?: Partial<Type>
): ProxyBuilder<Type, SubType> {
  const built: Partial<Type> = { ...defaultValues };
  const builder = new Proxy(
    {},
    {
      get: function (_target, prop) {
        if (prop === 'build') return () => built as Type;

        return (value: any) => {
          built[prop as keyof Type] = value;
          // 返回时断言为保留Type的构建器类型
          return builder as ProxyBuilder<Type, SubType>;
        };
      },
    }
  );

  return builder as ProxyBuilder<Type, SubType>;
}

type User = {
  type: 'admin' | 'basic';
  name: string;
  age: number;
};

const basicUserBuilder = () =>
  proxyBuilder<User, Omit<User, 'type'>>({ type: 'basic' });

const jane = basicUserBuilder()
  // .type('admin') // 此处触发类型错误,符合隐藏属性的需求
  .name('Jane')
  .age(42)
  .build(); // 现在返回类型为User,符合预期

修改说明

  1. 泛型传递修正:让ProxyBuilder的属性方法返回ProxyBuilder<Type, SubType>,确保原始目标类型Type不会被覆盖。
  2. 类型断言修正:代理中返回构建器时,断言为ProxyBuilder<Type, SubType>,而非SubType,维持类型链的正确性。
  3. 类型安全优化:将built的类型从any改为Partial<Type>,提升类型安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:11:20