Giving a method generics in Luau

I want to define a function like this:

function Class:GetList(something: {[number]: T}): {[number]: T}

But I don’t know where to put the <T>.

It doesn’t work after function, doesn’t work before or after Class, doesn’t work before or after GetList and doesn’t work after the parenthesis or after the return type either.

How do I tell Luau that this function is generic? I feel like this has the same issues as trying to assign to a field in self, that is, you have to do something like this:

	local something: Something = {}
	self.something = something

But I feel like it would look even weirder to do that with methods…

2 Likes

Venturing a guess here, since I don’t use typed Luau like this, but I think any works for this?

That doesn’t tell the type checker that both Ts have to be the same, which is what I’m trying to do here.

I hope this can help:

According to Type checking | Luau, there doesn’t seem to be a way. You could feasibly do this at runtime by calling typeof or checking metatables, which seems to be the next best thing.

A more complex version of the function signature would be this:

function Class:GetList(tbl: {[number]: T}, poll: (() -> {[number]: T})?): {[number]: T}

In this case, if poll is present, it will be called and the result moved into a copy of tbl.

Can the type checker infer this correctly?

function Class:GetList(tbl: {[number]: any}, poll)
	local built: typeof(tbl) = {}
	table.move(tbl, 0, #tbl, 0, built)

	if poll then
		local more = poll()
		table.move(more, 0, #more, #built, built)
	end

	return built
end

Not exactly, Test is required to have its generic argument specified at compile time :(

Hence why I asked here :stuck_out_tongue:

1 Like

For anyone wandering, generic functions are actually possible and you can write them like this:

-- Returns a random item in a table
function GetRandom<T>(tbl: {T}): T?
	return tbl[math.random(1, #tbl)]
end

local numbers = {1, 2, 3}
local strings = {"Hello", "World", "!"}

local randomNumber = GetRandom(numbers) -- returns a number!
local randomString = GetRandom(strings) -- returns a string!

It is also possible having more than one type parameter:

-- Searches a value in a table and returns its key
function GetKey<Tkey, TValue>(tbl: {[Tkey]: TValue}, value: TValue): Tkey?
	for key, itemValue in pairs(tbl) do
		if itemValue == value then
			return key
		end
	end

	return nil
end

Hope this helps!

I know its been like 4 years since this was brought up, but since nobodys actually answered the question I might as well say something for people coming back to this. I doubt you can make a generic function in a table like that, but you might be able to define that function normally and then reference it in the table.

function GetList<T>(something: {[number]: T}) : {[number]: T}
    return something
end

Class.GetList = GetList