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

如何在TypeScript中实现必选单个可选属性的类型约束?

更简洁实现“必选且仅选单个属性”的TypeScript类型定义

针对你需要实现「必须且只能定义接口中某一个属性」的需求,无需手动编写多个单个属性必选的接口,可通过映射类型+联合类型的方式动态生成目标类型,代码更简洁且易于维护(后续新增属性时无需修改类型定义)。

实现代码

// 基础可选属性接口
export interface OptionalIds {
  entityA_Id?: number;
  entityB_Id?: number;
  entityC_Id?: number;
}

// 工具类型:生成仅指定键必选、其余键为undefined的类型
type ExactlyOne<T, K extends keyof T = keyof T> = K extends keyof T 
  ? { [P in keyof T]: P extends K ? T[P] : undefined } & { [P in K]-?: Exclude<T[P], undefined> }
  : never;

// 最终目标类型:必选且仅能选OptionalIds中的一个属性
export type RestrictedOptionalIds = ExactlyOne<OptionalIds>;

代码解释

  • ExactlyOne<T, K> 是泛型工具类型:
    • 遍历T的所有键K,对每个键生成两种约束的交叉类型:
      1. 所有键的类型:如果是当前遍历的K则保留原类型,否则设为undefined(确保其余属性无法传入有效值)
      2. 强制当前K为必选属性(通过-?移除可选修饰符),并排除undefined(确保该属性必须传入有效值)
  • 最终RestrictedOptionalIds会自动展开为「仅entityA_Id必选」「仅entityB_Id必选」「仅entityC_Id必选」三种类型的联合,完全满足需求。

验证示例

// 合法:仅传入entityA_Id
const valid1: RestrictedOptionalIds = { entityA_Id: 1 };

// 合法:仅传入entityB_Id
const valid2: RestrictedOptionalIds = { entityB_Id: 2 };

// 不合法:传入多个属性
const invalid1: RestrictedOptionalIds = { entityA_Id: 1, entityB_Id: 2 }; // 类型报错

// 不合法:未传入任何属性
const invalid2: RestrictedOptionalIds = {}; // 类型报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:20:19