Reproduction Steps
Create a new place, copy this source code into a script:
Source Code
--!strict
local function f(e: "foo"|"bar"|"baz")
if e == "foo" then
local v: "foo" = e;
elseif e == "bar" then
local v: "bar" = e;
else
local v: "baz" = e;
end
end
local function g(e: number|string|boolean)
if type(e) == "number" then
local v: number = e;
elseif type(e) == "string" then
local v: string = e;
else
local v: boolean = e;
end
end
Expected Behavior
I’d expect the type of argument e
of function f
to be of type “baz” after the two type refinements.
Actual Behavior
It is instead of type "foo"|"bar"|"baz"
.
I also included an equivalent function that shows the behavior with non-enum intersection types, namely, number|string|boolean
, which works as expected.
Also, I think this might be a more general problem where the enum cannot narrow via a negative case. You can get similar results with assertions.
Workaround
Use any
type liberally. Or be explicit about the last else
clause.
Issue Area: Engine
Issue Type: Other
Impact: Moderate
Frequency: Rarely