Skip to content

Commit f6eb85d

Browse files
committed
Bug Fix: mergeAll refactoring, fix #284
1 parent 3729471 commit f6eb85d

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

src/index.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -1192,12 +1192,21 @@ export interface IntersectionC<CS extends [Mixed, Mixed, ...Array<Mixed>]>
11921192
unknown
11931193
> {}
11941194

1195-
const mergeAll = (us: Array<unknown>): any => {
1196-
let r: unknown = us[0]
1197-
for (let i = 1; i < us.length; i++) {
1195+
const mergeAll = (base: any, us: Array<any>): any => {
1196+
let r: any = base
1197+
for (let i = 0; i < us.length; i++) {
11981198
const u = us[i]
1199-
if (u !== r) {
1200-
r = Object.assign(r, u)
1199+
if (u !== base) {
1200+
// `u` contains a prismatic value or is the result of a stripping combinator
1201+
if (r === base) {
1202+
r = Object.assign({}, u)
1203+
continue
1204+
}
1205+
for (const k in u) {
1206+
if (u[k] !== base[k] || !r.hasOwnProperty(k)) {
1207+
r[k] = u[k]
1208+
}
1209+
}
12011210
}
12021211
}
12031212
return r
@@ -1241,9 +1250,9 @@ export function intersection<CS extends [Mixed, Mixed, ...Array<Mixed>]>(
12411250
us.push(validation.value)
12421251
}
12431252
}
1244-
return errors.length > 0 ? failures(errors) : success(mergeAll(us))
1253+
return errors.length > 0 ? failures(errors) : success(mergeAll(u, us))
12451254
},
1246-
codecs.length === 0 ? identity : a => mergeAll(codecs.map(codec => codec.encode(a))),
1255+
codecs.length === 0 ? identity : a => mergeAll(a, codecs.map(codec => codec.encode(a))),
12471256
codecs
12481257
)
12491258
}

test/PathReporter.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ describe('PathReporter', () => {
88
assert.deepStrictEqual(PathReporter.report(t.number.decode(function() {})), [
99
'Invalid value <function0> supplied to : number'
1010
])
11-
assert.deepStrictEqual(PathReporter.report(t.number.decode(function f() {})), ['Invalid value f supplied to : number'])
11+
assert.deepStrictEqual(PathReporter.report(t.number.decode(function f() {})), [
12+
'Invalid value f supplied to : number'
13+
])
1214
})
1315

1416
it('should say something whene there are no errors', () => {

test/intersection.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,20 @@ describe('intersection', () => {
4747
})
4848

4949
it('should decode a prismatic value', () => {
50-
const T = t.intersection([t.type({ a: t.string }), t.type({ b: NumberFromString })])
51-
assertSuccess(T.decode({ a: 'a', b: '1' }), { a: 'a', b: 1 })
50+
const T1 = t.intersection([t.type({ a: t.string }), t.type({ b: NumberFromString })])
51+
assertSuccess(T1.decode({ a: 'a', b: '1' }), { a: 'a', b: 1 })
52+
const T2 = t.intersection([t.type({ b: NumberFromString }), t.type({ a: t.string })])
53+
assertSuccess(T2.decode({ a: 'a', b: '1' }), { a: 'a', b: 1 })
54+
const T3 = t.intersection([t.type({ b: NumberFromString }), t.type({ a: t.string }), t.type({ c: t.string })])
55+
assertSuccess(T3.decode({ a: 'a', b: '1', c: 'c' }), { a: 'a', b: 1, c: 'c' })
56+
const T4 = t.intersection([
57+
t.type({ b: NumberFromString }),
58+
t.type({ a: t.string }),
59+
t.type({ c: NumberFromString })
60+
])
61+
assertSuccess(T4.decode({ a: 'a', b: '1', c: '2' }), { a: 'a', b: 1, c: 2 })
62+
const T5 = t.intersection([t.type({ b: NumberFromString }), t.type({})])
63+
assertSuccess(T5.decode({ b: '1' }), { b: 1 })
5264
})
5365

5466
it('should fail decoding an invalid value', () => {

0 commit comments

Comments
 (0)