gcanti / tcomb-validation

Validation library based on type combinators
MIT License
400 stars 23 forks source link

Unexpected behavior of intersections in strict mode #70

Open ArmorDarks opened 5 years ago

ArmorDarks commented 5 years ago

In strict mode, intersections of interfaces are always returning errors.

Consider this example:

const TypeA = t.interface({ one: t.String, two: t.String })
const TypeB = t.interface({ two: t.String })

const Type = t.interface({
  test: t.intersection([TypeA, TypeB])
}, 'Type')

const val = {
  test: {
    one: 'Test1',
    two: 'Test2'
  }
}

const res = t.validate(val, Type, { strict: true })
console.log(res)

That example basically unfulfillable. It will always result in an error:

    Struct {
      errors:
       [ Struct {
           message: 'Invalid value "Test1" supplied to /test/one: Nil',
           actual: 'Test1',
           expected: [Function],
           path: [Array] } ],
      value: { test: { one: 'Test1', two: 'Test2' } } }

Despite technically val fulfils TypeA & TypeB intersection.

In non-strict mode, works as intended.

I understand why this happens and straight out of the box I don't know if there any good solution for it. However, that's definitely not how intersections usually work in typed systems.

Maybe intersections should be treated as non-strict even in strict mode?