如何定义仅为A或B、不可同时包含两者的TypeScript类型?
TypeScript 实现互斥联合类型(二选一,禁止同时包含两类属性)
现有以下类型定义:
type FromSnapshot = { snapshotId: string; }; type NewInstance = { version: string; storageGB: number; };
直接使用 type DatabaseConfig = FromSnapshot | NewInstance 作为联合类型时,会允许对象同时包含两类属性(比如同时存在snapshotId、version和storageGB),不符合只能二选一的需求,且要求不能手动给每个类型添加反向never属性(例如给NewInstance添加snapshotId?: never)。
解决方案:通用互斥联合类型工具
定义一个通用工具类型ExclusiveUnion,自动处理两个类型的互斥逻辑:
type ExclusiveUnion<T, U> = | (T & Record<Exclude<keyof U, keyof T>, never>) | (U & Record<Exclude<keyof T, keyof U>, never>);
使用工具类型定义目标类型
type DatabaseConfig = ExclusiveUnion<FromSnapshot, NewInstance>;
逻辑说明
Exclude<keyof U, keyof T>:提取出U类型中独有的属性键Record<..., never>:将这些独有键的类型设为never,意味着对象若包含这些键会触发类型错误- 最终的联合类型包含两种互斥情况:仅保留
T的属性(U独有键为never)、仅保留U的属性(T独有键为never),实现严格二选一的约束
测试示例
// ✅ 合法:仅包含FromSnapshot属性 const validFromSnapshot: DatabaseConfig = { snapshotId: "s123" }; // ✅ 合法:仅包含NewInstance属性 const validNewInstance: DatabaseConfig = { version: "v1", storageGB: 10 }; // ❌ 非法:同时包含两类属性,类型检查报错 const invalidConfig: DatabaseConfig = { snapshotId: "s123", version: "v1", storageGB: 10 };
内容的提问来源于stack exchange,提问作者Josh M.
相关产品推荐
相关产品推荐

