From d898b06bfe00a9271bb5dd5feb8d78a15311050e Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Tue, 29 Oct 2019 23:34:44 -0700 Subject: [PATCH] Add TS utils. Closes #345 --- lib/index.d.ts | 15 +++++++++++++++ test/index.ts | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/index.d.ts b/lib/index.d.ts index 3eefa496..8c6a23bb 100755 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -440,3 +440,18 @@ export function wait(timeout?: number): Promise; * Returns a Promise that never resolves. */ export function block(): Promise; + + +export namespace ts { + + /** + * Defines a type that can must be one of T or U but not both. + */ + type XOR = (T | U) extends object ? (internals.Without & U) | (internals.Without & T) : T | U; +} + + +declare namespace internals { + + type Without = { [P in Exclude]?: never }; +} diff --git a/test/index.ts b/test/index.ts index adb37048..93af87bb 100755 --- a/test/index.ts +++ b/test/index.ts @@ -320,3 +320,18 @@ expect.type(await Hoek.block()); expect.error(Hoek.block(123)); // $lab:types:on$ + + +// ts + +interface X { a: number; }; +interface Y { b: number; }; + +function xor(input: Hoek.ts.XOR): number { + + return input.a || input.b || 10; +} + +xor({ a: 1 }); +xor({ b: 2 }); +expect.error(xor({ a: 1, b: 2 }));