Intersection types

An intersection R1 & R2 behaves as a value that conforms to both record shapes. Field access is only allowed when both sides agree on the field name and its type.

Shared prop on intersection type

Not yet implemented
Env
oneAndTwo : { sharedProp: Number; sharedPropDiffType: Bool; oneProp: String }
          & { sharedProp: Number; sharedPropDiffType: Number; twoProp: String }
Source
oneAndTwo.sharedProp
Inferred
Number   (field present in both, same type)

NOT YET IMPLEMENTED: intersection field resolution.

F# test body
X.PropAccN [ "oneAndTwo"; "sharedProp" ]
|> solve env None
|> shouldSolveType (Mono BuiltinTypes.number)

Disjoint prop on intersection type

Expected error
Env
oneAndTwo : { sharedProp: Number; sharedPropDiffType: Bool; oneProp: String }
          & { sharedProp: Number; sharedPropDiffType: Number; twoProp: String }
Source
oneAndTwo.oneProp
Error
'oneProp' only exists on one side of the intersection

Open design question: should this fail, or return a bottom-type?

F# test body
X.PropAccN [ "oneAndTwo"; "oneProp" ]
|> solve env None
|> shouldFail

Shared prop, diff type on intersection type

Expected error
Env
oneAndTwo : { sharedProp: Number; sharedPropDiffType: Bool; oneProp: String }
          & { sharedProp: Number; sharedPropDiffType: Number; twoProp: String }
Source
oneAndTwo.sharedPropDiffType
Error
Field present on both sides but with incompatible types (Bool vs Number)

Open design question: could be widened to a common base type if one existed (e.g. Object). For now we fail.

F# test body
X.PropAccN [ "oneAndTwo"; "sharedPropDiffType" ]
|> solve env None
|> shouldFail