With luau’s strict typing everything must be statically resolvable by the interpreter. This becomes an issue when one wishes to put the members of one table into another.
For example, I have a class with a prototype. This is what I have to do right now to get all the members to be available to the prototype, the constructor, and the type.
type Object = {
foo: ()->(),
bar: ()->()
}
local proto = {
foo = function() end,
bar = function() end
}
function make() : Object
return {
foo = proto.foo,
bar = proto.bar
}
end
This is time-consuming and annoying, because any new member now has to be added to three places (type declaration, proto
implementation, and make
assignment).
What I want to do, and would do before strict luau, is dynamically assign the members like this:
function make()
local new = {}
table.foreach(proto, function(k, v)
new[k] = v
end)
return new
end
But this doesn’t get captured by luau, because the members of proto
become anonymized as k
and v
.
So my suggestion is clone and append functions. These functions can be interpreted directly by luau to prevent the members of proto
from being anonymized.
function make() : Object
return table.clone(proto)
end
-- ...
function make() : AnotherObject
return table.append(proto, {
per_instance_property = {},
another_per_inst_prop = 1234
})
end
Once this is available, I can reduce the number of foo
and bar
definitions from three each to only one each:
local proto = {
foo: ()->(),
bar: ()->()
}
function make : Object
return table.clone(proto)
end
type Object = typeof(make())
My ideal API for these functions is
table.clone(source) -> new
table.append(source, target) -> target