The type works if it describes only a simple table, but not completely if declaring it involves the use of the ‘setmetatable<T, U>’ type function as described below:
- If the union field of the table is either an instance of the union, it throws an error:
--!strict
local Class = {}
Class.__index = Class
export type ClassType = setmetatable<{
foo : boolean | number
}, typeof(Class)>
local function newClass(): ClassType
return setmetatable({
foo = true
}, Class) --TypeError: Has the 2nd component of the union as `number`, and `boolean` is not exactly `number`
end
- vice versa:
return setmetatable({
foo = 3.14
}, Class) --TypeError: Has the 1st component of the union as `boolean`, and `number` is not exactly `boolean`
- But if the union has a singleton, it works if the value’s type is the said singleton:
export type ClassType = setmetatable<{
foo : "hello" | number
}, typeof(Class)>
local function newClass(): ClassType
return setmetatable({
foo = "hello"
}, Class) --works as expected
end
- and throws an error if it’s not:
return setmetatable({
foo = -77
}, Class) --TypeError: Has the 1st component of the union as `"hello"`, and `number` is not exactly `"hello"`