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

如何处理带有互斥参数的TypeScript函数?

问题描述

我希望addNumbers函数始终返回数字,将b或c与a相加。参数a为必填项,b和c同样为必填项,但二者互斥,即不能同时传入。

我尝试了以下写法:

function addNumbers1({
  a,
  b,
  c,
}: { a: number } & (
  | { b: number; c?: never }
  | { c: number; b?: never }
)): 
// 此处TypeScript报错:"Function lacks ending return statement and return type does not include 'undefined'.(2366)"
number {

  if (b) {
    return a + b;
  }

  if (c) {
    return a + c;
  }
}

出现上述Function lacks ending return statement and return type does not include 'undefined'.(2366)错误后,我尝试添加校验确保b或c始终被定义,避免无返回值的情况:

function addNumbers2({
  a,
  b,
  c,
}: { a: number } & (
  | { b: number; c?: never }
  | { c: number; b?: never }
)): number | string {

  // 添加该行代码防止b或c为undefined
  if (b === undefined && c === undefined) return "error";

  // 此时b或c必然已定义,以下条件之一应始终返回数字
  // 但TypeScript仍报错:Function lacks ending return statement and return type does not include 'undefined'.(2366)

  if (b) {
    return a + b;
  }

  if (c) {
    return a + c;
  }
}

我又尝试了另一种写法:

function addNumbers3({
  a,
  b,
  c,
}: { a: number } & (
  | { b: number; c?: never }
  | { c: number; b?: never }
)): number | string {

  // 再次确保b或c其中一个已定义
  if (b === undefined && c === undefined) return "error";

  if (b) {
    return a + b;
  } else {
    // 但此时报错:"'c' is possibly 'undefined'.(18048)"
    // 明明已经做了校验,为什么会这样?
    return a + c;
  }
}

请问处理该问题的最佳方案是什么?我希望保留当前的函数参数结构。

编辑说明:如果将示例中的number类型改为string类型,示例会更合理——检查数字0的真值时存在另一个问题。


解决方案

问题核心有两点:一是TypeScript无法自动通过联合类型的结构完成精准类型收窄,二是用if (b)这种真值判断会漏掉b=0的合法情况。以下是适配你需求的最优方案:

方案一:严格存在性判断+运行时兜底

完全保留你原有的参数结构,通过严格的存在性判断替代真值判断,同时添加运行时兜底避免非法调用:

function addNumbers({
  a,
  b,
  c,
}: { a: number } & (
  | { b: number; c?: never }
  | { c: number; b?: never }
)): number {
  // 运行时兜底:防止非TS环境调用或类型绕过
  if (b === undefined && c === undefined) {
    throw new Error("必须传入b或c中的一个");
  }

  // 用严格存在性判断替代真值判断,避免漏掉b=0的情况
  if (b !== undefined) {
    return a + b;
  }

  // 此时TypeScript能通过联合类型推断出c必然存在,无需额外断言
  return a + c;
}

为什么这个方案可行?

  1. 用b !== undefined替代if (b),解决了数字0被误判为“不存在”的问题;
  2. 兜底判断抛出错误而非返回字符串,保证函数始终返回数字,符合你最初的需求;
  3. 当排除b存在的情况后,TypeScript能根据联合类型的约束,自动推断出c必然存在,不会再报undefined错误。

为什么之前的写法会报错?

  1. addNumbers1报错:if (b)是真值判断,会漏掉b=0的合法情况,导致代码可能走到函数末尾无返回值,TypeScript因此报错;
  2. addNumbers2报错:同样的真值判断问题,当b=0或c=0时,两个if分支都不会触发,函数依然可能无返回值;
  3. addNumbers3报错:if (b)的真值判断无法让TypeScript区分“b=0”和“b不存在”两种情况,所以进入else分支后,TypeScript依然认为c可能是undefined。

内容的提问来源于stack exchange,提问作者Björn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:18:11