diff --git a/src/null-or.test.ts b/src/null-or.test.ts new file mode 100644 index 0000000..d998d0a --- /dev/null +++ b/src/null-or.test.ts @@ -0,0 +1,10 @@ +import * as $ from './index.js' + +test('simple', () => { + const union = $.or($.string, $.number) + const assert = $.nullOr(union) + expect(assert(null)).toEqual(null) + expect(assert(1)).toEqual(1) + expect(assert('foo')).toEqual('foo') + expect(() => assert(true)).toThrow('') +}) diff --git a/src/or.test.ts b/src/or.test.ts index 9c51dea..6c8ae80 100644 --- a/src/or.test.ts +++ b/src/or.test.ts @@ -1,6 +1,7 @@ import * as $ from './index.js' test('or', () => { - const r = $.or($.number, $.string)(JSON.parse('"foo"')) + const assert = $.or($.number, $.string) + const r = assert(JSON.parse('"foo"')) expect(r).toEqual('foo') }) diff --git a/src/or.ts b/src/or.ts index 6b39676..90d7141 100644 --- a/src/or.ts +++ b/src/or.ts @@ -1,12 +1,12 @@ -import type { Assert } from './prelude.js' +import type { Assert, Asserted } from './prelude.js' import { inspect } from 'util' -const or: []>(...as: T) => T[number] = - (...as) => - value => { +const or = + []>(...as: As) => + (value: unknown) => { for (const a of as) { try { - return a(value) + return a(value) as Asserted } catch (err) { continue } diff --git a/src/prelude.ts b/src/prelude.ts index 76408d2..3d9cdfb 100644 --- a/src/prelude.ts +++ b/src/prelude.ts @@ -71,3 +71,6 @@ export type OptionalIfUndefinedOnly = { export type OptionalIfUndefined = Omit> & OptionalIfUndefinedOnly + +export type IntersectionOfUnion = + (T extends unknown ? (_: T) => unknown : never) extends (_: infer R) => unknown ? R : never