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

TypeScript泛型元组创建对象有自动补全,访问属性却报错?

TypeScript泛型元组合并类型报错分析与解决

问题复现

你尝试通过泛型元组合并多个对象类型,但访问属性时出现类型错误,代码如下:

const foo = {
  user: {
    id: 1,
  },
};
const bar = {
  hello: "goodbye",
};

type Test<T extends Record<PropertyKey, any>[]> = (
  T[number] extends any ? (k: T[number]) => void : never
) extends (k: infer I) => void
  ? I
  : never;

const test: Test<[typeof foo, typeof bar]> = {
  user: {
    id: 1
  },
  hello: "23",
};

console.log(test.user);
// 类型“{ user: { id: number; }; } | { hello: string; }”上不存在属性“user”。
// 类型“{ hello: string; }”上不存在属性“user”。ts(2339)

问题原因

你的Test类型误用了分布式条件类型,最终生成的是元组元素类型的联合类型,而非期望的交叉类型:

  1. T[number]展开为元组所有元素的联合类型(typeof foo | typeof bar);
  2. 条件类型左侧是“裸类型参数”时,TypeScript会触发分布式逻辑,将联合中的每个成员单独代入条件,生成((k: typeof foo) => void) | ((k: typeof bar) => void)的函数联合类型;
  3. 后续通过infer I推导时,得到的I是原联合类型typeof foo | typeof bar。

当test的类型为联合类型时,访问user属性会报错——联合类型的类型检查要求所有成员都拥有该属性才能安全访问,而typeof bar并没有user属性。

至于创建对象时能自动补全,是因为TypeScript允许包含联合所有成员属性的对象赋值给联合类型(该对象是联合类型的子类型)。

解决方案

方案1:递归交叉元组元素(直观易懂)

直接递归遍历元组,将每个元素的类型交叉合并:

const foo = {
  user: {
    id: 1,
  },
};
const bar = {
  hello: "goodbye",
};

// 递归合并元组元素为交叉类型
type MergeTuple<T extends any[]> = T extends [infer First, ...infer Rest]
  ? First & MergeTuple<Rest>
  : {};

const test: MergeTuple<[typeof foo, typeof bar]> = {
  user: { id: 1 },
  hello: "23",
};

console.log(test.user); // 正常访问,类型为{ id: number }
console.log(test.hello); // 正常访问,类型为string

方案2:修改原Test类型,避免分布式条件类型

通过将T[number]包裹在数组中阻止分布式逻辑,同时利用函数参数的逆变特性推导交叉类型:

const foo = {
  user: {
    id: 1,
  },
};
const bar = {
  hello: "goodbye",
};

type Test<T extends Record<PropertyKey, any>[]> = (
  // 用[]包裹T[number],避免触发分布式条件类型
  [T[number]] extends [infer U] ? (k: U) => void : never
) extends (k: infer I) => void
  ? I
  : never;

const test: Test<[typeof foo, typeof bar]> = {
  user: { id: 1 },
  hello: "23",
};

console.log(test.user); // 无报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:53