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

TypeScript元组类型收窄疑问:两类场景类型推断为何不同?

TypeScript联合元组类型推断差异问题解析

下面两个TypeScript场景中,都是返回包含不同类型的联合元组,但类型推断表现却不一致:

场景1:返回两组对象+undefined的联合元组

export function functionThatReturnsTurpleObjects():
  | [{ a: number }, undefined]
  | [undefined, { a: number }]
 {
  if (Math.random() > 0.5) {
    return [undefined, { a: 1 }];
  }
  return [{ a: 1 }, undefined];
}

function execute1() {
  const [res1, res2] = functionThatReturnsTurpleObjects();
  if (res2) {
    return res2;
  }
  // TypeScript可以正确推断res1不可能为undefined
  res1.a;
}

场景2:返回对象+undefined和undefined+字符串的联合元组

function functionThatReturnsTurpleObjectAndString():
  | [{ a: number }, undefined]
  | [undefined, string] {
  if (Math.random() > 0.5) {
    return [undefined, "1"];
  }
  return [{ a: 1 }, undefined];
}

function execute2() {
  const [res1, res2] = functionThatReturnsTurpleObjectAndString();
  if (res2) {
    return res2;
  }
  // TypeScript抛出错误:TS18048: res1 is possibly undefined,但实际res1不可能为undefined
  res1.a;
}

差异原因解析

这是因为TypeScript的联合类型收窄规则在处理元组时,依赖元组对应位置类型的可辨识性:

  • 场景1中,联合元组的第二个元素非undefined时类型完全一致(都是{a: number})。当res2被收窄为{a: number}时,TypeScript能明确排除[{a: number}, undefined]分支;当res2为undefined时,自然锁定到[{a: number}, undefined]分支,因此能正确推断res1不可能为undefined。
  • 场景2中,联合元组的第二个元素非undefined时类型不同({a: number} vs string)。当res2为undefined时,TypeScript无法仅通过这一点反向锁定唯一分支——因为两个分支的第二个位置都可能是undefined,且第一个位置的类型没有共同可辨识特征,导致无法自动推断res1此时必然是{a: number}。

修复方案

要让场景2的推断正常工作,可以手动添加类型断言,或者使用明确的类型守卫:

// 方案1:类型断言
function execute2Fixed() {
  const [res1, res2] = functionThatReturnsTurpleObjectAndString();
  if (res2) {
    return res2;
  }
  (res1 as {a: number}).a;
}

// 方案2:自定义类型守卫
function isFirstTuple(tuple: ReturnType<typeof functionThatReturnsTurpleObjectAndString>): tuple is [{a: number}, undefined] {
  return tuple[0] !== undefined;
}

function execute2Fixed2() {
  const tuple = functionThatReturnsTurpleObjectAndString();
  if (tuple[1]) {
    return tuple[1];
  }
  if (isFirstTuple(tuple)) {
    tuple[0].a;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:53:10