I have some structures with unions and intersections that I am trying to type check and ensure exact equality. However for some reason when I put these types into a table type (like Z1/Z2) the equality check fails, whereas comparing them directly (M1/M2) the equality check succeeds.
type A1 = {a: true}
type B1 = {b: true}
type C1 = {c: true}
type M1 = A1 & (B1 | C1)
type A2 = {a: true}
type B2 = {b: true}
type C2 = {c: true}
type M2 = A2 & (B2 | C2)
type Z1 = {
E: {[string]: M1};
}
type Z2 = {
E: {[string]: M2};
}
local Z: Z1 = nil
-- These two lines have type errors:
local Checked: Z2 = Z
Checked = Z :: Z2
The error I am getting on the first line is:
Type '(B1 | C1) & A1' could not be converted into 'B2 | C2'; none of the union options are compatible.
It looks like the A2 type is being lost track of.
The error I get on the second line is:
Cannot cast Z1 into Z2 because the types are unrelated.
Here’s the full message for this first one:
What seems to be the same issue can also be demonstrated with a more concise example:
type A = {Y: boolean}
type C = A & {X: {b: boolean} & {c: boolean}}
local V: C = {
Y = true;
-- Get an error about extra field 'c', the type checker only sees {b: boolean}.
X = {b = true, c = true};
}