lua-language-server
lua-language-server copied to clipboard
generic param no hint
How are you using the lua-language-server?
Visual Studio Code Extension (sumneko.lua)
Which OS are you using?
Windows
What is the issue affecting?
Completion
Expected Behaviour
---删除物品
---@class pb.S2C_DelItem
---@field itemId integer 物品id
---发送协议到客户端
---@generic T
---@param cmd pb.`T` 命令名
---@param args T
---@return T
function sendToClient(cmd, args)
return nil
end
local ret = sendToClient("S2C_DelItem",{
itemId = 1, -- 无法推断出args为pb.S2C_DelItem类型,输入itemId无字段类型提示
})
ret.itemId -- 返回值能推断出为pb.S2C_DelItem类型,输入itemId有字段类型提示
Actual Behaviour
能正确推断出泛型参数类型并有代码提示
Reproduction steps
如上代码
Additional Notes
No response
Log File
No response
泛型参数已经匹配了 pb.T 所以不会继续匹配第二个参数了, 泛型函数不能你这样用
在我的使用經驗中,泛型参數在 ---@param 階段下只能用來 捕獲 (capture) param type,而不能 強制 (enforce) param type。跟這個 discussion 的提問有點類似: https://github.com/LuaLS/lua-language-server/discussions/2669
該 discussion 內提出的建議是修改 syntax 中間用1個 factory function => 按 cmd 來返回1個 接受對應 type 的 closure 當然這個涉及修改 syntax,你或者會認為不合適 😇
---删除物品
---@class pb.S2C_DelItem
---@field itemId integer 物品id
---发送协议到客户端
---@generic T
---@param cmd pb.`T` 命令名
---@return fun(args: T): T
local function sendToClientWrapper(cmd)
return nil -- 要返回 closure,可以參考下 discussion 內是怎樣寫
end
local ret = sendToClientWrapper("S2C_DelItem") {
--< 可以觸發字段 auto complete
}
如果要不改 syntax,那感覺只能用 @overload 方式來處理了
這個你得用法方式來 auto gen 1個 meta definition file 較好
類似這裡提到的: https://github.com/LuaLS/lua-language-server/discussions/2723#discussioncomment-9842624
在你的 use case 大概會是這樣
---删除物品
---@class pb.S2C_DelItem
---@field itemId integer 物品id
---增加物品
---@class pb.S2C_AddItem
---@field itemId integer 物品id
---@field count integer 物品數量
---@enum (key) Cmds
local Cmds = {
S2C_DelItem = 1,
S2C_AddItem = 2,
}
---发送协议到客户端
---@generic T: table
---@param cmd Cmds
---@param args T
---@return T
---@overload fun(cmd: "S2C_DelItem", args: pb.S2C_DelItem): pb.S2C_DelItem
---@overload fun(cmd: "S2C_AddItem", args: pb.S2C_AddItem): pb.S2C_AddItem
local function sendToClient(cmd, args)
return nil
end
local ret = sendToClient("S2C_DelItem", {
-- auto complete 會提示 itemId
})
local ret2 = sendToClient("S2C_AddItem", {
-- auto complete 會提示 itemId, count
})
(但是 luals 的 @overload 機制好像是有點小 bug,不確定會否在什麼時候不能正確地 type narrow 的 🙈 )