From d8ad096698cd9fc2fc285fbd6b51b24cc482c7f2 Mon Sep 17 00:00:00 2001 From: fabriziopapi Date: Thu, 20 May 2021 12:17:29 +0200 Subject: [PATCH 1/2] Fixed issue about decoding an Intersection composed by a type and a type composed by an empty interface and another type --- docs/modules/index.ts.md | 2 +- src/index.ts | 21 ++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/docs/modules/index.ts.md b/docs/modules/index.ts.md index 6d42e2077..d4ede0f94 100644 --- a/docs/modules/index.ts.md +++ b/docs/modules/index.ts.md @@ -1827,7 +1827,7 @@ export const array = (codec: C, name: string = `Array<${codec.n name, (u): u is Array> => UnknownArray.is(u) && u.every(codec.is), (u, c) => - chain(UnknownArray.validate(u, c), us => ... + UnknownArray.validate(u, c).chain(us => ... ``` Added in v1.0.0 diff --git a/src/index.ts b/src/index.ts index a20ac9cf6..cc588e2c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1168,19 +1168,14 @@ export interface IntersectionC]> > {} const mergeAll = (base: any, us: Array): any => { - let r: any = base - for (let i = 0; i < us.length; i++) { - const u = us[i] - if (u !== base) { - // `u` contains a prismatic value or is the result of a stripping combinator - if (r === base) { - r = Object.assign({}, u) - continue - } - for (const k in u) { - if (u[k] !== base[k] || !r.hasOwnProperty(k)) { - r[k] = u[k] - } + if (!us.some(u => u !== base)) { + return base + } + const r: any = {} + for (const u of us) { + for (const k in u) { + if (!r.hasOwnProperty(k) || u[k] !== base[k]) { + r[k] = u[k] } } } From b10c1ad5bc60b646660e48e5e678305bea7f7668 Mon Sep 17 00:00:00 2001 From: fabriziopapi Date: Thu, 20 May 2021 15:25:51 +0200 Subject: [PATCH 2/2] test for intersection with inner exact of a empty interface --- test/exact.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/exact.ts b/test/exact.ts index b0b6bed03..78871482e 100644 --- a/test/exact.ts +++ b/test/exact.ts @@ -51,6 +51,16 @@ describe('exact', () => { assertSuccess(T.decode({ foo: 'foo' })) }) + it('should succeed validating a valid value (intersection with inner exact of a empty interface)', () => { + const T = t.intersection([ + t.type({ foo: t.string }), + t.exact(t.intersection([t.interface({}), t.partial({ bar: t.number })])) + ]) + assertSuccess(T.decode({ foo: 'foo', bar: 1 })) + assertSuccess(T.decode({ foo: 'foo', bar: undefined })) + assertSuccess(T.decode({ foo: 'foo' }), { foo: 'foo' }) + }) + it('should succeed validating a valid value (refinement)', () => { // tslint:disable-next-line: deprecation const T = t.exact(t.refinement(t.type({ foo: t.string }), p => p.foo.length > 2))