lua-language-server
lua-language-server copied to clipboard
Table of tables of functions
As requested creating an issue for my question on how to approach this situation. Guessing there is no way currently given I was asked to create an issue :)
Discussed in https://github.com/sumneko/lua-language-server/discussions/1331
Originally posted by muppet9010 July 14, 2022 I have the below concept and aren't sure how to go about properly type defining it. I have it as below and the typing almost works fine, apart from within the inner functions the parameters aren't getting their type.
---@alias EntityTypes table<string, EntityTypeDetails>
---@class EntityTypeDetails
---@field GetEntityName fun(name: string, count: integer): string
---@type EntityTypes
local EntityTypeDetails = {
tree = {
GetEntityName = function(name, count)
return name .. tostring(count)
end
},
rock = {
GetEntityName = function(name, count)
return name .. tostring(count + 1)
end
}
}
local x = EntityTypeDetails["tree"].GetEntityName("grey", 5)
So the function knows its types:
But the parameter doesn't:
Here I expected completions (perhaps I have also messed up something)
to me it looks like this is related to this issue
if it isn't tell me so I can open a separate issue
I've also run into this problem in a task running library I'm writing:
local M = {}
---@class Task
---@field name string
---@field description? string
---@field requires? string[]
---@field enabled? boolean
---@field run fun(ctx: Runtime, data: table): nil
-- Define a task
---@param task Task
---@return Task
M.task = function(task) end
return M
When I'm defining the function itself the ctx
parameter loses it types:
But when I look at the run
field itself, the types are correct:
At the moment I'm working around it by adding types, but it seems redundant as you can see that the types are there, they are just lost when creating the function.
M.task({
name = "task"
---@param ctx Runtime
run = function (ctx)
local user = ctx:user
end
})
If it makes it easier to implement then rather than doing inheritance I don't see any large downsides in doing it with the @type
applied to the function at creation or a new @interface
which is bespoke for this situation. So something that would work like this:
---@alias GetEntityNameInterface fun(name: string, count: integer): string
---@alias EntityTypes table<string, EntityTypeDetails>
---@class EntityTypeDetails
---@field GetEntityName GetEntityNameInterface
---@type EntityTypes
local EntityTypeDetails = {
tree = {
---@interface GetEntityNameInterface
GetEntityName = function(name, count)
return name .. tostring(count)
end
},
rock = {
---@interface GetEntityNameInterface
GetEntityName = function(name, count)
return name .. tostring(count + 1)
end
}
}
local x = EntityTypeDetails["tree"].GetEntityName("grey", 5)
}