danvk / effective-typescript

Effective TypeScript 2nd Edition: 83 Specific Ways to Improve Your TypeScript
https://effectivetypescript.com
Other
1.53k stars 226 forks source link

Exclusive Or and the Optional never Trick #16

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

Exclusive Or and the Optional never Trick

Effective TypeScript: Exclusive Or and the Optional never Trick

https://effectivetypescript.com/2021/11/11/optional-never/

aleclofabbro commented 2 years ago

Thanks Dan for this blog ! :) what about type XOR<A, B> = Exclude<A | B, A & B>

danvk commented 2 years ago

That's a cute idea (and mathematically correct!) but unfortunately TypeScript isn't able to follow along:

type XOR<A, B> = Exclude<A | B, A & B>

type ExclusiveThing = XOR<ThingOne, ThingTwo>;
//   ^? type ExclusiveThing = ThingOne | ThingTwo

The issue is that the Exclude generic filters unions; it won't break up a "base" type like an interface or a string.

Beraliv commented 4 months ago

Hey @danvk! Thank you for mentioning ts-essentials.

This type hasn't been added to TypeScript since 2017, you can read more in https://github.com/microsoft/TypeScript/issues/14094

The utility type existed in ts-essentials for a long time but it didn't have a support of variadic XOR which last year was implemented in ts-xor - https://github.com/microsoft/TypeScript/issues/14094#issuecomment-1695887662 (It's also supported in ts-essentials@10)