LuaLS / LuaLS/lua-language-server

How do I document a generic class (JS Promises)

未关闭
#1,532 4 条评论 3 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

enhancement feat/generic
主要语言
Lua
星标
4.4k
派生
442
PR 合并指标
30 天内没有已合并 PR

描述

Hello everyone! First of all, thank you for the amazing work on this server. It's really great and extremelly fast to use!

I've a question about how can I use the type system to properly type a Promise-like table that I'm creating. Right now I need to type this piece of code:

local Promise = require ".../promise"
Promise:new(function(resolve, reject)
  -- do some async stuff...
  if some_async_true_status then
    resolve(some_async_result)
  else
    reject(some_async_error)
  end
end):next(function(result) -- < `resolve()` value here
  print(result)
end):catch(function(err) -- < `reject()` value here
  print(err)
end)

This a Promise-like implementation that I'm doing for my neovim plugin which I'm trying to get a similar API as the Javascript Promise.

My question here is, how can I type this to the callee function knows what this is going to be returned from that callback? Currently, I'm trying to play around with @generic but, I can't get the server to properly understand what I mean by my types:

local Promise = {}

---@generic T
---@class Promise<T>
---@field new(executor: fun(resolve: fun(result: T), reject: fun(err: any)))): Promise
---@field next(fn: fun(result: T)): Promise <<<<< here I'm returning `self`
---@field catch(fn: fun(err: any)): Promise <<<<< here I'm returning `self` as well

function Promise:new(executor)
  local promise = { ... }
  -- ... some operations
  return setmetatable(promise, {
    __index = self,
  })
end

function Promise:next(fn)
  -- some operations...
  return self
end

function Promise:catch(fn)
  -- some operations...
  return self
end

----------------------
-- Here is how I want to use it:

---@return Promise<string>
function my_function_that_return_promise()
  return Promise:new(function(resolve, reject)
    -- .....
    resolve("hello")
  end)
end

my_function_that_return_promise():next(function(result)
  print(result) -- << here I want the server to show `result` is a `string`
end)

For reference, this is how we can do this exactly thing using typescript:

const myPromise = new Promise<string>((resolve, reject) => {
  // ...
  resolve("hello")
})

myPromise
  .then((result) => console.log(result)) // < `result` will have `string` type
  .catch((err) => console.log(err))

Thank you for the awesome work! Sorry if I didn't make myself clear, let me know if I need to provide any further information.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 Promise 示例中的 @generic 和 @class 注解开始,追踪 language server 当前如何通过 new()、next() 和 catch() 推断回调类型。完成的标准是确定所请求的泛型传播是否受支持,或是否需要对类型系统进行明确定义的更改,并且最终回调中的 string 结果能够被推断出来。

由索引模型根据 Issue 内容生成。

评估

技术栈
lua, neovim
领域
devtools
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
需要澄清
新手友好度
20/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。