LuaLS / LuaLS/lua-language-server
How do I document a generic class (JS Promises)
まだ誰も着手していません。
- 主要言語
- 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.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
Promise の例にある @generic および @class アノテーションから始め、language server が現在 new()、next()、catch() を通じて callback の型をどのように推論しているかを追跡します。要求された generic の伝播がサポートされているのか、定義された型システムの変更が必要なのかを判断し、final callback で string の結果が推論されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- lua, neovim
- 領域
- devtools
- issue の種類
- 機能追加
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 20/100