Skip to content

Add Xor type#1254

Merged
sindresorhus merged 8 commits intosindresorhus:mainfrom
benzaria:Xor
Oct 8, 2025
Merged

Add Xor type#1254
sindresorhus merged 8 commits intosindresorhus:mainfrom
benzaria:Xor

Conversation

@benzaria
Copy link
Contributor

@benzaria benzaria commented Sep 29, 2025

adding Xor type (remake #1156 )

@benzaria benzaria marked this pull request as ready for review September 29, 2025 23:57
source/xor.d.ts Outdated
Returns `false` if the giving type is `never`, else return it.
*/
type IfNever<T> = [T] extends [never] ? false : T;
// TODO: use to simplify `And`, `Or` types
Copy link
Collaborator

@som-sm som-sm Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean rewrite And and Or with Xor? I feels it makes more sense to write Xor using And and Or, like:

type Xor<A extends boolean, B extends boolean> = Or<And<Not<A>, B>, And<A, Not<B>>>;

But this would currently not work because Not doesn't handle never properly. So, your implementation is fine, just remove this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh no, the comment point to IfNever that i want to use to simplify this pattern

type T = _Or<If<IsNever<A>, false, A>, If<IsNever<B>, false, B>>

which is used in Or and repeats multiple unnecessary checks trough the process and IfNever is a custom private types between Xor and Or which directly infer the result:

type T = _Or<IfNever<A>, IfNever<B>>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to use And and Or for this, but the extra conditions didn’t make much sense to me — why prettify things and lose performance?

A working Xor would look like this:

type Xor<A extends boolean, B extends boolean> = And<Or<A, B>, Not<And<A, B>>>;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh no, the comment point to IfNever that i want to use to simplify this pattern

No, please remove this abstraction and use <If<IsNever<T>, false, T>, similar to how it’s done in Or:

type-fest/source/or.d.ts

Lines 78 to 79 in 3bd9de6

export type Or<A extends boolean, B extends boolean> =
_Or<If<IsNever<A>, false, A>, If<IsNever<B>, false, B>>; // `never` is treated as `false`

It's quite simple and easy to understand and doesn't need further abstraction.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to use And and Or for this, but the extra conditions didn’t make much sense to me — why prettify things and lose performance?

There's NO performance loss as such, and it's actually better doing it with And and Or because it helps validate that And and Or themselves are implemented correctly. But, it's fine for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll use ur seggestion for IfNever.
For the And and Or version of Xor it does work perfectly, I test it. If it's better to make it this way tell me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the And and Or version of Xor it does work perfectly, I test it. If it's better to make it this way tell me.

Yeah, let's do it using And, Or & Not.


Either definition works:

  1. A working Xor would look like this:

    type Xor<A extends boolean, B extends boolean> = And<Or<A, B>, Not<And<A, B>>>;
  2. I feels it makes more sense to write Xor using And and Or, like:

    type Xor<A extends boolean, B extends boolean> = Or<And<Not<A>, B>, And<A, Not<B>>>;

benzaria and others added 2 commits October 5, 2025 19:17
Co-authored-by: Som Shekhar Mukherjee <49264891+som-sm@users.noreply.github.com>
@som-sm som-sm changed the title add: Xor type Add Xor type Oct 6, 2025
@sindresorhus sindresorhus merged commit ad04bc5 into sindresorhus:main Oct 8, 2025
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants