teal-language / tl

The compiler for Teal, a typed dialect of Lua

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Type guard doesn't work properly with unions

RobertBouillon opened this issue · comments

Type guards with unions that include a record (table) will only check for the table. Other values included in the union will not be captured.

global record Foo
  bar : string
end

global function repro(x:Foo|string|nil) : integer
  local y = x
  if y is string | Foo then
    return 1
  elseif y is nil then
    return 2
  end
  return 3 -- string falls through here!
end

print(repro({} as Foo)) --1
print(repro("1"))       --3
print(repro(nil))       --2

Workaround

You can add a manual type guard in place of the union, which then gets inferred, but only if:

  1. it's in an elseif block and
  2. the if statement starts with an is expression
global function repro(x:Foo|string|nil) : integer
  local y = x
  if y is nil then
    local z : nil = y 
    return 2
  elseif type(y) == "table" or type(y) == "string" then
    local z : Foo | string = y
    return 1
  end
  return 3 --No fall through
end

Thanks for the report!

This should also function as a workaround:

  if y is string or y is Foo then

Thanks for the report!

This should also function as a workaround:

  if y is string or y is Foo then

I like that better, thanks!

Incredible library, by the way. Takes a lot of the sting out of large Lua scripts, especially coming from C#, Java, and TS.