typescript Feb 19, 2026
XOR Types for Mutually Exclusive Options
Enforce exactly one of two shapes at compile time.
XOR is perfect for APIs where two options are mutually exclusive.
Type
xor.ts
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
type XOR<T, U> = (T & Without<U, T>) | (U & Without<T, U>)
type ById = { id: string }
type ByEmail = { email: string }
type Lookup = XOR<ById, ByEmail>
function getUser(input: Lookup) {
return input
}
getUser({ id: 'u1' })
getUser({ email: 'a@b.com' })
// @ts-expect-error: both provided
getUser({ id: 'u1', email: 'a@b.com' })