From 3013aaddf2905b8d03170e7c88b86596d5c6e40b Mon Sep 17 00:00:00 2001 From: Mirek Rusin Date: Mon, 29 Jan 2024 15:50:30 +0100 Subject: [PATCH] fix(and): fixing typing for and --- src/and.test.ts | 36 +++++++++++++++++++++++++++++++++--- src/and.ts | 12 +++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/and.test.ts b/src/and.test.ts index 9d36d33..0c58e78 100644 --- a/src/and.test.ts +++ b/src/and.test.ts @@ -1,9 +1,39 @@ import * as $ from './index.js' test('and', () => { - const r: { name: string } = $.and( - $.object({ firstName: $.nullishOr($.string), lastName: $.nullishOr($.string), name: $.string }), + const r = $.and( + $.object({ firstName: $.nullishOr($.string), lastName: $.nullishOr($.string), name: $.unknown }), $.object({ name: $.string }) )(JSON.parse('{"name":"Foo","role":"admin"}')) - expect(r).toEqual({ name: 'Foo', role: 'admin' }) + const name: string = r.name + expect(name).toEqual('Foo') +}) + +test('parametric', () => { + const known = { + string: $.string, + number: $.number + } as const + const assertType = $.oneOf( + 'string', + 'number' + ) + const assertUnknown = $.exact({ + type: assertType, + value: $.unknown + }) + const assert = + (type: T) => + $.and( + assertUnknown, + value => + $.object({ + type: $.eq(type ?? value.type), + value: known[type ?? value.type] + })(value) + ) + assert('number')(JSON.parse('{"type":"number","value":42}')) + expect(() => assert('number')(JSON.parse('{"type":"number","value":"42"}'))).toThrow() + assert('string')(JSON.parse('{"type":"string","value":"42"}')) + expect(() => assert('string')(JSON.parse('{"type":"string","value":42}'))).toThrow() }) diff --git a/src/and.ts b/src/and.ts index 98371a8..64702f4 100644 --- a/src/and.ts +++ b/src/and.ts @@ -1,12 +1,14 @@ import type { Assert } from './prelude.js' -type $ = Assert +type Z = + (value: A) => + B type And = { - (a: $): $ - (a: $, b: $): $ - (a: $, b: $, c: $): $ - (a: $, b: $, c: $, d: $): $ + (a: Assert): Assert + (a: Assert, b: Z): Assert + (a: Assert, b: Z, c: Z): Assert + (a: Assert, b: Z, c: Z, d: Z): Assert } const and: And =