New Type Solver: Table types with union fields declared using 'setmetatable<T, U>' gives type error at instance creation

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"`