1+
2+ /**
3+ Returns `false` if the giving type is `never`, else return it.
4+ */
5+ export type IfNever < T > = [ T ] extends [ never ] ? false : T ;
6+
7+ /**
8+ Returns a boolean for whether either of two given types are true.
9+
10+ Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
11+
12+ @example
13+ ```
14+ import type {Xor} from 'type-fest';
15+
16+ type TT = Xor<true, false>;
17+ //=> true
18+
19+ type TF = Xor<true, false>;
20+ //=> true
21+
22+ type FT = Xor<false, true>;
23+ //=> true
24+
25+ type FF = Xor<false, false>;
26+ //=> false
27+ ```
28+
29+ Note: When `boolean` is passed as an argument, it is distributed into separate cases, and the final result is a union of those cases.
30+ For example, `Xor<false, boolean>` expands to `Xor<false, true> | Xor<false, false>`, which simplifies to `true | false` (i.e., `boolean`).
31+ @example
32+ ```
33+ import type {Xor} from 'type-fest';
34+
35+ type A = Xor<false, boolean>;
36+ //=> boolean
37+
38+ type B = Xor<boolean, false>;
39+ //=> boolean
40+
41+ type C = Xor<true, boolean>;
42+ //=> true
43+
44+ type D = Xor<boolean, true>;
45+ //=> true
46+
47+ type E = Xor<boolean, boolean>;
48+ //=> boolean
49+ ```
50+
51+ Note: If `never` is passed as an argument, it is treated as `false` and the result is computed accordingly.
52+
53+ @example
54+ ```
55+ import type {Xor} from 'type-fest';
56+
57+ type A = Xor<true, never>;
58+ //=> true
59+
60+ type B = Xor<never, true>;
61+ //=> true
62+
63+ type C = Xor<false, never>;
64+ //=> false
65+
66+ type D = Xor<never, false>;
67+ //=> false
68+
69+ type E = Xor<boolean, never>;
70+ //=> boolean
71+
72+ type F = Xor<never, boolean>;
73+ //=> boolean
74+
75+ type G = Xor<never, never>;
76+ //=> false
77+ ```
78+
79+ @see And, Or
80+ */
81+ export type Xor < A extends boolean , B extends boolean > = _Xor < IfNever < A > , IfNever < B > > ; // `never` is treated as `false`
82+
83+ export type _Xor < A extends boolean , B extends boolean > =
84+ A extends true
85+ ? B extends true
86+ ? false
87+ : true
88+ : B extends true
89+ ? true
90+ : false ;
91+
92+ type T = Xor < never , never >
93+ // ^?
94+
95+ export { } ;
0 commit comments