foxts
Version:
Opinionated collection of common TypeScript utils by @SukkaW
36 lines (33 loc) • 1.46 kB
TypeScript
/**
* Skip evaluating `U` if `T` is `unknown`.
*/
type EvalIfNotUnknown<T, U> = unknown extends T ? never : U;
/**
* Resolve mapped types and show the derived keys and their types when hovering in
* VS Code, instead of just showing the names those mapped types are defined with.
*/
type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
/**
* Get the keys of T without any keys of U.
*/
type Without<T, U> = {
[P in Exclude<keyof T, keyof U>]?: never;
};
/**
* Restrict using either exclusively the keys of `T` or exclusively the keys of `U`.
*
* No unique keys of `T` can be used simultaneously with any unique keys of `U`.
*
* @example
* ```ts
* const myVar: XOR<{ data: object }, { error: object }>
* ```
*
* Supports from 2 up to 8 generic parameters.
*
* More: https://github.com/maninak/ts-xor/tree/master#description
* */
type XOR<A, B, C = unknown, D = unknown, E = unknown, F = unknown, G = unknown, H = unknown> = Prettify<(Without<B & C & D & E & F & G & H, A> & A) | (Without<A & C & D & E & F & G & H, B> & B) | EvalIfNotUnknown<C, Without<A & B & D & E & F & G & H, C> & C> | EvalIfNotUnknown<D, Without<A & B & C & E & F & G & H, D> & D> | EvalIfNotUnknown<E, Without<A & B & C & D & F & G & H, E> & E> | EvalIfNotUnknown<F, Without<A & B & C & D & E & G & H, F> & F> | EvalIfNotUnknown<G, Without<A & B & C & D & E & F & H, G> & G> | EvalIfNotUnknown<H, Without<A & B & C & D & E & F & G, H> & H>>;
export type { XOR };