Type `{T} | {T}` raises type error in for loop

Reproduction Steps

Create a new place, add this script:

--!strict

--MyType is a sort of "typed union" or variant or whatever you want to call it.
type ShapeType = {
	Shape: "Rectangle";
	Width: number;
	Height: number;
	Vertices: {Vector2};
} | {
	Shape: "Square";
	Size: number;
	Vertices: {Vector2};
};

local function GetNewShape(): ShapeType
	if math.random(2) == 1 then
		return {
			Shape = "Rectangle";
			Width = 5;
			Height = 10;
			Vertices = {Vector2.new(0, 0), Vector2.new(5, 0), Vector2.new(5, 10), Vector2.new(0, 10)};
		};
	else
		return {
			Shape = "Square";
			Size = 5;
			Vertices = {Vector2.new(0, 0), Vector2.new(5, 0), Vector2.new(5, 5), Vector2.new(0, 5)};
		};
	end
end

local function PrintAllVertices(shape: ShapeType)
	for i, vertex in shape.Vertices do
		print(vertex);
	end
end

Expected Behavior

Iā€™d expect that I can use shape.Vertices as my iterator, as its type is {Vector2} | {Vector2}, which is equivalent to {Vector2}.

Actual Behavior

I get a warning.

warning-luau-type

Workaround

I think this may have something to do with this variable being in the place of a callable. Some workarounds:

  • Cast to a {Vector2}
  • Pass this value to pairs

workarounds

Issue Area: Studio
Issue Type: Other
Impact: Moderate
Frequency: Sometimes

3 Likes

Thank you for the report, we have created an internal ticket for this and we hope to fix this in the future.

3 Likes

We are working on a new type-checking system that will fix this error, but unfortunately it will take many more months to be ready for release.

One work-around I can suggest is to make a unique type for {Vector2} as each of them right now is a unique instance and that prevents the iteration from recognizing that both properties are exactly the same.

type VertexArray = {Vector2}

--MyType is a sort of "typed union" or variant or whatever you want to call it.
type ShapeType = {
	Shape: "Rectangle";
	Width: number;
	Height: number;
	Vertices: VertexArray;
} | {
	Shape: "Square";
	Size: number;
	Vertices: VertexArray;
};
2 Likes