LuaLS / LuaLS/lua-language-server

How do I document a generic class (JS Promises)

Abierto
#1,532 4 comentarios 3 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

enhancement feat/generic
Lenguaje dominante
Lua
Estrellas
4.4k
Forks
442
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con las anotaciones @generic y @class del ejemplo de Promise y sigue cómo el language server infiere actualmente los tipos de callback mediante new(), next() y catch(). La tarea estará terminada cuando se determine si la propagación genérica solicitada es compatible o requiere un cambio definido en el sistema de tipos, con el resultado de tipo string inferido en el callback final.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
lua, neovim
Área
devtools
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
20/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.