lua-language-server
lua-language-server copied to clipboard
Help: How can I properly write the types (@class) for a promise-like table?
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.
Dose not support generic class for now.
i also ran into this issue recently and and just here to politely +1 this if possible :)