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

如何定义公共成员非空、独有成员可空的TypeScript联合类型?

TypeScript 如何定义公共成员非可选、独有成员可选的联合兼容类型?

问题描述

我需要定义一个函数,它可以接收类型A或B作为参数,这两个类型有部分公共成员,也有各自独有的成员。我希望在函数体内能直接引用仅属于A或B的成员,同时明确这些成员在运行时可能为undefined,但公共成员必须保持非可选状态。

当前尝试的两种方式都无法满足需求:

  1. 使用type ArgType = A | B:访问独有成员时TypeScript会报错,因为它无法确定当前参数是A还是B
  2. 使用type ArgType = A | B | Partial<A> | Partial<B>:会导致A和B的所有成员都变成可选,包括公共成员

示例代码如下:

type A = {
  common: number;
  a_only: string;
}

type B = {
  common: number;
  b_only: string;
}

type ArgType = A | B; // 无法满足需求:访问a_only/b_only会报错

function takesAorB(arg: ArgType) {
  if (arg.common > 1) {
    // 这里没问题,common在A和B中都存在且非可选
  }
  if (arg.a_only?.length) {
    // 报错:属性'a_only'不存在于类型'B'上
  }
  if (arg.b_only?.length) {
    // 报错:属性'b_only'不存在于类型'A'上
  } 
}

解决方案

可以通过自定义工具类型,构造一个公共成员非可选、独有成员可选的类型,具体步骤如下:

  1. 提取两个类型的公共属性,保留其非可选状态
  2. 分别提取两个类型的独有属性,将其转为可选状态
  3. 将上述三部分交叉合并,得到最终的目标类型

实现代码:

type A = {
  common: number;
  a_only: string;
}

type B = {
  common: number;
  b_only: string;
}

// 提取两个类型的公共属性
type CommonProps<T, U> = Pick<T, Extract<keyof T, keyof U>>;
// 提取类型T相对于U的独有属性
type UniqueProps<T, U> = Pick<T, Exclude<keyof T, keyof U>>;

// 构造目标类型:公共属性非可选,两个类型的独有属性转为可选
type ArgType = CommonProps<A, B> & Partial<UniqueProps<A, B>> & Partial<UniqueProps<B, A>>;

function takesAorB(arg: ArgType) {
  if (arg.common > 1) {
    // common仍为非可选,无需额外检查
  }
  if (arg.a_only?.length) {
    // a_only的类型为string | undefined,符合预期
    console.log(arg.a_only);
  }
  if (arg.b_only?.length) {
    // b_only的类型为string | undefined,符合预期
    console.log(arg.b_only);
  } 
}

// 测试用例:符合要求的参数都能正常传入
takesAorB({ common: 2, a_only: "test" });
takesAorB({ common: 3, b_only: "demo" });
takesAorB({ common: 1 }); // 也允许只传公共成员

原理说明

  • CommonProps<A, B>:提取A和B的共同键(这里是common),得到类型{ common: number },保留原有的非可选约束
  • Partial<UniqueProps<A, B>>:提取A独有的键(a_only)并转为可选,得到{ a_only?: string }
  • Partial<UniqueProps<B, A>>:提取B独有的键(b_only)并转为可选,得到{ b_only?: string }
  • 交叉类型&会把这三部分合并,最终得到的类型既保证了公共成员的非可选性,又让独有成员变成可选(即类型为对应值或undefined)

内容的提问来源于stack exchange,提问作者JSBձոգչ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 21:57:45