LuaLS / LuaLS/lua-language-server

How do I document a generic class (JS Promises)

Offen
#1,532 4 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

enhancement feat/generic
Vorherrschende Sprache
Lua
Sterne
4.4k
Forks
442
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit den Annotationen @generic und @class im Promise-Beispiel und verfolge, wie der Language Server derzeit Callback-Typen über new(), next() und catch() ableitet. Erledigt ist die Aufgabe, wenn festgestellt wurde, ob die angeforderte Weitergabe von Generics unterstützt wird oder eine definierte Änderung am Typsystem erfordert, wobei das String-Ergebnis im finalen Callback abgeleitet wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
lua, neovim
Bereich
devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
20/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.