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:

```lua
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:

```lua
local Promise = {}

---@generic T
---@class Promise
---@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
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:

```typescript
const myPromise = new Promise((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() 推論 callback 型別。完成的標準是確定所要求的 generic 傳播是否受到支援,或是否需要對型別系統進行明確定義的變更,並且最終 callback 中的 string 結果能夠被推論出來。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
lua, neovim
領域
devtools
Issue 類型
功能
難度
5/5
預估耗時
一週以上
活躍度
停滯
描述清晰度
需要釐清
新手友好度
20/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。