Reproduction Steps
Copy/paste this script into a blank place:
Source Code
--!strict
--Use of "ShapeType" field allows me to discriminate the kind of shape in a function which simply takes
--a Shape argument.
type Square = {ShapeType: "Square"} & {Size: number};
type Rectangle = {ShapeType: "Rectangle"} & {Width: number; Height: number};
type Circle = {ShapeType: "Circle", Radius: number};
type Shape = Square | Rectangle | Circle;
--[[
Type Error: (19,1) Type 's' could not be converted into '{| ShapeType: "Square" |} & {| Size: number |}'
caused by:
Not all intersection parts are compatible. Type 's' could not be converted into '{| ShapeType: "Square" |}'
caused by:
Property 'ShapeType' is not compatible. Type 'string' could not be converted into '"Square"'
--]]
local s: Square = {
ShapeType = "Square";
Size = 4;
};
--I can suppress the error by casting the string constant into itself. *Weird*.
local r: Rectangle = {
ShapeType = "Rectangle" :: "Rectangle";
Width = 5;
Height = 3;
};
--Circle doesn't have this problem because it isn't a union type. This is a toy example, but in my
--real use-case, making the type a union helps cut away a lot of boilerplate & avoid copy/paste
--errors, as one of the types is a template.
local c: Circle = {
ShapeType = "Circle";
Radius = 8;
};
Expected Behavior
I shouldn’t get a type error.
Actual Behavior
I get a type error.
You can see the type checker is only angry about how I cast to the Square type:
Workaround
You can workaround the issue by casting the string constant to itself, as demonstrated with the “Rectangle” type in the above screenshot. And as always, you can cast to any
to suppress the warnings, but then you lose type checking on that field.
You can also avoid type intersections that involve string constants to fix the problem, but that’s a lame solution.
Issue Area: Studio
Issue Type: Other
Impact: Low
Frequency: Sometimes