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

如何创建支持默认参数的工厂函数,生成需必填未默认参数的函数

实现带默认参数的工厂函数,生成的函数自动校验必填项

需求

  • 创建一个可传入默认参数的工厂函数
  • 工厂生成的函数要求未被设置为默认值的参数为必填项,但同时能接受所有参数(允许覆盖默认值)

问题代码

用户尝试的代码无法正确推导出生成函数的参数类型,导致无法校验必填项:

interface Alpha {
  a: string;
  b: string;
}

export function alpha(params: Alpha) {
  console.log(JSON.stringify(params));
}

export function alphaDefaults(defaults: Partial<Alpha>) {
  // Not sure what Defaults should be...
  const func = (params: Defaults) => alpha({ ...defaults, ...params });
  return func;
}

const fn2 = alphaDefaults({});

// should complain about missing a and b
fn2({});

const fn3 = alphaDefaults({ a: "A" });

// should complain about missing b
fn3({ a: "NotA" });
fn3({});

const fn4 = alphaDefaults({ b: "B" });
// should complain about missing a
fn4({ b: "NotB" });
fn4({});

const fn5 = alphaDefaults({ a: "A", b: "B" });
// should not complain
fn5({ a: "NotA" });
fn5({ b: "NotB" });
fn4({ a: "Hi", b: "There" });

解决方案

通过TypeScript泛型捕获默认值的具体类型,推导出生成函数的参数类型,实现必填项校验:

interface Alpha {
  a: string;
  b: string;
}

export function alpha(params: Alpha) {
  console.log(JSON.stringify(params));
}

// 用泛型D捕获传入的默认值的具体类型
export function alphaDefaults<D extends Partial<Alpha>>(defaults: D) {
  // 提取未设置默认值的属性作为必填项
  type RequiredParams = Omit<Alpha, keyof D>;
  // 生成函数的参数:必填项 + 所有可选属性(允许覆盖默认值)
  type FuncParams = RequiredParams & Partial<Alpha>;
  
  const func = (params: FuncParams) => alpha({ ...defaults, ...params });
  return func;
}

// 测试验证
const fn2 = alphaDefaults({});
// ❌ 报错:缺少属性a和b(符合预期)
// fn2({});

const fn3 = alphaDefaults({ a: "A" });
// ❌ 报错:缺少属性b(符合预期)
// fn3({ a: "NotA" });
// fn3({});

const fn4 = alphaDefaults({ b: "B" });
// ❌ 报错:缺少属性a(符合预期)
// fn4({ b: "NotB" });
// fn4({});

const fn5 = alphaDefaults({ a: "A", b: "B" });
// ✅ 无报错(符合预期)
fn5({ a: "NotA" });
fn5({ b: "NotB" });
fn5({ a: "Hi", b: "There" });

关键说明

  1. 泛型捕获默认值类型:泛型D会自动推断传入的defaults的具体属性,TypeScript能精准知道哪些属性已经设置了默认值。
  2. 推导必填项类型:Omit<Alpha, keyof D>会移除Alpha中已经被默认值覆盖的属性,剩下的就是必须传入的必填项。
  3. 兼容覆盖场景:通过RequiredParams & Partial<Alpha>交叉类型,既保证必填项必须传入,又允许传入所有Alpha属性用于覆盖默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:21:18