Skip to main content
← Gists
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' })