Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript是否支持互斥类型?_Typescript - Fatal编程技术网

Typescript是否支持互斥类型?

Typescript是否支持互斥类型?,typescript,Typescript,我有一个接受参数的方法。我希望Typescript验证传入的对象(在Typescript编译时,我知道运行时是另一个动物)只满足一个允许的接口 例如: interface Person {ethnicity: string;} interface Pet {breed: string;} function getOrigin(value: Person ^ Pet){...} getOrigin({}); //Error getOrigin({ethnicity: 'abc'}); //OK

我有一个接受参数的方法。我希望Typescript验证传入的对象(在Typescript编译时,我知道运行时是另一个动物)只满足一个允许的接口

例如:

interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: Person ^ Pet){...}

getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK
getOrigin({ethnicity: 'abc', breed: 'def'});//Error
我意识到
Person^Pet
不是有效的Typescript,但这是我想尝试的第一件事,而且似乎是合理的。

您可以使用:

但最后一句话不会出错:

getOrigin({ethnicity: 'abc', breed: 'def'}); // fine!
如果希望这是一个错误,则需要使用:


为了补充Nitzan的答案,如果您真的想强制执行
种族
品种
是互斥指定的,您可以使用映射类型强制执行某些字段的缺失:

type Not<T> = {
    [P in keyof T]?: void;
};
interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: Person & Not<Pet>): void;
function getOrigin(value: Pet & Not<Person>): void;
function getOrigin(value: Person | Pet) { }

getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK

var both = {ethnicity: 'abc', breed: 'def'};
getOrigin(both);//Error
类型不={
[P in keyof T]?:无效;
};
接口人{种族:字符串;}
接口宠物{品种:字符串;}
函数getOrigin(值:Person&Not):void;
函数getOrigin(值:Pet&Not):void;
函数getOrigin(值:Person | Pet){}
getOrigin({})//错误
getOrigin({种族:'abc'})//好啊
getOrigin({breed:'def'})//好啊
var两者={种族:'abc',品种:'def'};
getOrigin(两者)//错误
如中所述,您可以使用编写XOR类型:

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 Without={[P in Exclude]?:never};
类型XOR=(T | U)扩展对象?(无&U)|(无&T):T | U;
现在,您的示例起作用了:

interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: XOR<Person, Pet>) { /* ... */}

getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK
getOrigin({ethnicity: 'abc', breed: 'def'});//Error
接口人{种族:字符串;}
接口宠物{品种:字符串;}
函数getOrigin(值:XOR){/*…*/}
getOrigin({})//错误
getOrigin({种族:'abc'})//好啊
getOrigin({breed:'def'})//好啊
getOrigin({种族:'abc',品种:'def'})//错误

您可以使用专门用于解决此问题的微型npm软件包

使用它,您可以执行以下操作:

从'ts XOR'导入{XOR}
接口A{
a:字符串
}
接口B{
b:字符串
}
让A_XOR_B:XOR
A_XOR_B={A:'A'}//好的
A_XOR_B={B:'B'}//好的
A_XOR_B={A'A',B'B'}//失败
A_XOR_B={}//失败
充分披露:我是这个小包裹的作者。我发现我一直需要在不同的repo之间实现XOR类型。因此,我为我和社区发布了它,通过这种方式,我还可以使用自述文件和共享的jsdoc注释对它进行适当的文档记录。这个实现是@Guilherme Agostinelli从社区中共享的

您可以使用:


我想你要找的是。AFAIK TypeScript不支持独占类型。对于希望在一个接口的所有键中只保留一个属性的人,我建议使用联合类型并不能解决问题,这有点像OP要求用什么替换它,但是函数重载在这个用例中非常有效。XOR非常方便!如何扩展它以支持多个互斥类型?您能否扩展您的答案以支持
XOR
?您需要建立一个相应的链(我怀疑它是因为传递性而起作用的?!):
键入XOR3=XOR
@maninak参加派对有点晚了,但是(TS游乐场)会用
其中一个
恐怖的@tjfvi…:)完成你想要的
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;
interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: XOR<Person, Pet>) { /* ... */}

getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK
getOrigin({ethnicity: 'abc', breed: 'def'});//Error
interface Person {
  readonly discriminator: "Person"
  ethnicity: string
}

interface Pet {
  readonly discriminator: "Pet"
  breed: string
}

function getOrigin(value: Person | Pet) { }

getOrigin({ }) // Error
getOrigin({ discriminator: "Person", ethnicity: "abc" }) // OK
getOrigin({ discriminator: "Pet", breed: "def"}) // OK
getOrigin({ discriminator: "Person", ethnicity: "abc", breed: "def"}) // Error