LuaLS / LuaLS/lua-language-server

How do I document a generic class (JS Promises)

Ouverte
#1,532 4 commentaires 3 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

enhancement feat/generic
Langage dominant
Lua
Étoiles
4.4k
Forks
442
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par les annotations @generic et @class dans l’exemple de Promise et suivez la manière dont le language server infère actuellement les types des callbacks via new(), next() et catch(). Le travail est terminé lorsqu’il est déterminé si la propagation générique demandée est prise en charge ou nécessite une modification définie du système de types, avec le résultat de type string inféré dans le callback final.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
lua, neovim
Domaine
devtools
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
20/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.