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

TypeScript如何定义允许无、仅一个但禁止同时存在两个指定属性的类型

问题原因

你原先的写法错误地将需要禁止的属性声明为必填的never类型:b: never的语义是「必须存在b属性,且值的类型为never」,而never不存在合法的取值,这会导致你的三个接口本身就没有符合要求的合法实例,自然也无法实现你要的校验逻辑。
另外当你用{}作为NeitherANorB的替代时,由于空接口允许传入任意额外属性,自然也无法拦截同时存在a和b的场景。

解决方案

要表示「某个属性不允许存在」,正确的写法是将其声明为可选的never类型:属性名?: never,语义为「该属性要么不存在,要么存在时取值为never(无合法值)」。
修改后的完整代码如下:

interface JustA {
    a: string;
    b?: never;
}

interface JustB {
    b: string;
    a?: never;
}

interface NeitherANorB {
    a?: never;
    b?: never;
}

type NotBothAAndB = JustA | JustB | NeitherANorB;

function testMe(x: NotBothAAndB) {
    console.log(x);
}

testMe({}); // OK
testMe({ a: "HI!" }); // OK
testMe({ b: "SUP?" }); // OK
testMe({ a: "HI!", b: "SUP?" }); // 报错:不能将类型“{ a: string; b: string; }”分配给类型“NotBothAAndB”
通用扩展

如果需要更通用的互斥属性校验,可以封装通用工具类型:

type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
type OneOrNone<T, U> = XOR<T, U> | (Without<{}, T | U>;

// 使用示例
type NotBothAAndB = OneOrNone<{a:string}, {b:string}>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 12:48:04