lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

Is there a way to specify type aliases for variadic arg functions

Open vaderkos opened this issue 5 months ago • 4 comments

Is there any way to achieve proper inference of variadic arguments using aliases?

Image

a should be fun(a: table, b: string, c: integer): boolean but instead it's fun(...: table): boolean

I've also tried but it didn't work

--- @alias Predicate1<A> fun(a: A): boolean
--- @alias Predicate2<A, B> fun(a: A, b: B): boolean
--- @alias Predicate3<A, B, C> fun(a: A, b: B, c: C): boolean
--- @alias Predicate4<A, B, C, D> fun(a: A, b: B, c: C, d: D): boolean

--- @alias Predicate<A, B, C, D>
--- | Predicate1<A>
--- | Predicate2<A, B>
--- | Predicate3<A, B, C>
--- | Predicate4<A, B, C, D>

vaderkos avatar Aug 17 '25 21:08 vaderkos

AFAIK, there can only be one type for variadic arg i.e. if you write ...: A => it expects all variadic args to be of type A

For your specific use case which you at most have 4 args, I tested around and you can just write it as:

--- @alias Predicate<A, B, C, D> fun(a: A, b: B, c: C, d: D): boolean

---@type Predicate<table, string, integer>
local function test1(a, b, c)
    --> a: table, b: string, c: integer
    return true
end

---@type Predicate<integer>
local function test2(a)
    --> a: integer
    return false
end

Although in this case when you hover over test2, it will be shown as:

local test2: Predicate<integer>
function (a: integer, b: <B>, c: <C>, d: <D>)
  -> boolean

tomlau10 avatar Aug 18 '25 01:08 tomlau10

My use case rather involved any number of arguments

vaderkos avatar Aug 25 '25 15:08 vaderkos

Then it's just not supported currently in LuaLS I believe. 😕 It assumes the ... to be homogeneous (same type), which you can only specific 1 type for it.

If you still would like to use the @alias method, you can define as many arguments as you can. The annotation for table.unpack is also somewhat done in this way: https://github.com/LuaLS/lua-language-server/blob/24b9faa66332fca9f0df6e552ae9f3ca24c01821/meta/template/table.lua#L66-L85

  • instead of writing @return ...T (which means all are of the same generic type T
  • it uses @return T1, T2, xxx to support up to 10 different inferred return value type

tomlau10 avatar Aug 26 '25 06:08 tomlau10

Looks like a hack..

vaderkos avatar Aug 30 '25 13:08 vaderkos