`never` types can be cast to anything

Reproduction Steps

Copy this source into a script:

Source Code
--!strict

local value: string|number = "foo";

if type(value) == "string" then
	local s: string = value; --not an error -- good
	local n: number = value; --this should be an error
elseif type(value) == "number" then
	local s: string = value; --this should be an error
	local n: number = value; --not an error -- good
else
	local s: string = value; --this should be an error, but it isn't
	local n: number = value; --this should be an error, but it isn't
end

Expected Behavior

I’d expect an error on lines 12 & 13, as we’re casting an impossible value (type never) into a string & number, respectively.

Actual Behavior

I get no errors on those lines.

Also, note that you do get errors on line 7 & 9, which is expected, as we’ve narrowed the type down from string|number, and hence those assignments are invalid.

RobloxStudioBeta_KIyxEFLgjy

Workaround

There’s not really a workaround required, you just get worse typechecking because of it.

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

Create an issue on the Luau Repo for a faster response

Thanks for the report! We’ll take a look.

2 Likes

Hi there, sorry for letting this languish! I investigated the possibility of adding this warning in the past, but apparently failed to circle back with a response. Overall, from a theoretical standpoint, there’s nothing wrong with values at the never type being assigned to anything of any type at all. This is because never represents an impossible state. Based on the type of value there, for instance, that else branch is dead code that cannot be reached. As such, there’s no safety reason to provide a warning. Nevertheless, we did feel it could be useful to provide the warning, but ultimately decided against it because significant amounts of code in the wild are already relying on the fact that never is convertible to anything.

1 Like