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

如何在TypeScript中实现Props单选项的条件类型约束

实现Props单选项的条件类型约束问题解决方法

问题背景

现有如下结构的Props:

{
  option1,
  option2,
  option3,
  option4,
  general,
  otherprops
}

需求是确保同一时间仅能使用其中一个option。最初的类型定义如下:

interface MyTypes {
  option1: boolean
  option2: boolean
  option3: boolean
  general: boolean
  otherprops: string
}

尝试修改为以下类型来实现约束:

interface GeneralTypes{
  general: boolean
  otherprops: string
}

interface Option1Types{
  option1: boolean
}
interface Option2Types{
  option2: boolean
}
interface Option3Types{
  option3: boolean
}
 
type MyTypes = GeneralTypes & ( Option1Types | Option2Types | Option3Types )

但出现了以下类型错误:

Property 'option1' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
Property 'option2' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
Property 'option3' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '

解决方案

之前的写法错误在于:联合类型的每个分支仅包含自己的option属性,当你尝试访问某个option时,TypeScript无法确定当前实例属于哪个分支,因此会报错。要实现互斥选项的约束,需要让每个分支明确仅保留自身的option属性,其他option属性不存在或为never类型。

可以通过以下方式实现:

// 通用属性部分
interface GeneralTypes {
  general: boolean;
  otherprops: string;
}

// 定义所有可选option的键类型
type OptionKeys = 'option1' | 'option2' | 'option3';

// 生成单个option的类型,同时排除其他option
type SingleOption<K extends OptionKeys> = {
  [key in Exclude<OptionKeys, K>]?: never;
} & {
  [key in K]: boolean;
};

// 最终的Props类型:通用属性 + 单个互斥option
type MyTypes = GeneralTypes & (SingleOption<'option1'> | SingleOption<'option2'> | SingleOption<'option3'>);

代码解释

  1. OptionKeys:统一管理所有互斥的option键,方便后续维护。
  2. SingleOption<K>:
    • 通过Exclude<OptionKeys, K>排除当前option以外的所有键,并将它们设为?: never,确保这些属性不能被赋值(即使传入也会触发类型错误)。
    • 同时明确当前K对应的option为必填的boolean类型。
  3. MyTypes:将通用属性与单个互斥option的联合类型交叉,确保每个实例必须包含通用属性,且仅能拥有一个有效的option。

验证示例

// 合法:仅包含option1
const valid1: MyTypes = {
  general: true,
  otherprops: 'test',
  option1: true
};

// 合法:仅包含option2
const valid2: MyTypes = {
  general: false,
  otherprops: 'demo',
  option2: false
};

// 非法:同时包含option1和option2
const invalid1: MyTypes = {
  general: true,
  otherprops: 'error',
  option1: true,
  option2: true
}; // 类型错误:option2不能被赋值

// 非法:未包含任何option
const invalid2: MyTypes = {
  general: true,
  otherprops: 'error'
}; // 类型错误:缺少必填的option属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:05:42