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

TypeScript联合两种对象类型时无法正确推断类型的问题

解决TypeScript联合类型与Record类型的类型推断问题

问题分析

你定义的myType是{"204": {}}和Record<string, Record<string, number>>的联合类型,但在遍历Object.keys(param)时出现两个问题:

  • 即使判断code === "204",emptyRes的类型还是{} | Record<string, number>,无法精准缩小;
  • 非"204"分支报错,提示联合类型没有字符串索引签名。

核心原因:

  1. Object.keys()返回的是string[]类型,而非字面量类型,TypeScript无法通过code === "204"直接缩小param的类型;
  2. 联合类型中的Record<string, ...>本身可以包含"204"键,所以仅判断键值无法区分两个联合成员。

解决方案:自定义类型保护函数

通过类型保护函数明确区分两个联合成员,再分别处理:

type myType = {"204": {}} | Record<string, Record<string, number>>;

// 类型保护函数:判断是否是仅包含"204"键的对象
function is204Response(obj: myType): obj is {"204": {}} {
  return "204" in obj && Object.keys(obj).length === 1;
}

const foo = (param: myType) => {
  if (is204Response(param)) {
    // 这里param被缩小为{"204": {}}类型
    const emptyRes = param["204"]; // 类型准确为{}
  } else {
    // 这里param被缩小为Record<string, Record<string, number>>类型
    Object.keys(param).forEach(code => {
      const res = param[code]; // 类型准确为Record<string, number>,无报错
    });
  }
};

补充说明

如果你的业务场景中,Record<string, Record<string, number>>类型不会包含"204"键,也可以简化类型保护逻辑:

function is204Response(obj: myType): obj is {"204": {}} {
  return typeof obj["204"] === "object" && Object.keys(obj["204"]).length === 0;
}

关键是要让TypeScript明确当前param属于联合类型中的哪一个成员,才能实现精准的类型推断。

内容的提问来源于stack exchange,提问作者legends-killer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:54:23