Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning a custom class with a generic parameter causes unknown behaviour #3019

Closed
Joakker opened this issue Jan 1, 2025 · 4 comments
Closed

Comments

@Joakker
Copy link

Joakker commented Jan 1, 2025

How are you using the lua-language-server?

Visual Studio Code Extension (sumneko.lua)

Which OS are you using?

Windows

What is the issue affecting?

Type Checking

Expected Behaviour

When defining a file like

---@class Promise
Promise = {}

---@generic T
---@param func fun(value: T)
function Promise:and_then(func) end

---@param entity integer
---@return Promise<string?>
function get_name(entity) end

local name_promise = get_name(1)

The LSP should be able to tell that name is of type Promise<string?>

Actual Behaviour

The LSP is able to identify the type of name, however, it doesn't show the fields/methods of the class, and it doesn't infer anything about it either, ie, building from the example above

name:and_then(
    function(value)
        print(value)
    end
)

The LSP should be able to infer that value should be of type string?

Reproduction steps

Simply type in the code as shown above

Additional Notes

No response

Log File

No response

@CppCXY
Copy link
Collaborator

CppCXY commented Jan 1, 2025

luals does not support generic classes, and your way of describing generics in classes is also incorrect.

@tomlau10
Copy link
Contributor

tomlau10 commented Jan 1, 2025

For the closest promise-like annotation, you may want to see this example: #1532 (comment)
But it does need another fix beforehand: #2945 (comment) (which fixes a generic class has no completion).

However since no one has fully tested that fix, so it is not PRed.
You may try to finish it with tests if you would like to 😄

Below is a demo, with the suggested fix in #2945, as well as using the storing generic class with a temp field method explained in #1532, to show how a generic class can be achieved in luals currently

---@class Promise<T>: { __ResolveType: T }
Promise = {}

---@generic T
---@param self Promise<T>
---@param func fun(value: T)
function Promise:and_then(func) end

---@param entity integer
---@return Promise<string?>
function get_name(entity) end

local name_promise = get_name(1)

name_promise:and_then(function (value) --> value: string
    
end)

Do note that as CppCXY has mentioned, luals does not fully support generic classes currently. So there might still be other bugs even with the suggested fix get merged.

@Joakker
Copy link
Author

Joakker commented Jan 1, 2025

Unfortunately that didn't seem to solve the issue. It's not a big deal, though, as I was mainly concerned with not having to annotate every other parameter in the inevitable callback hell of my API.
Knowing that generics aren't robust enough to support this yet, I think I'll change my strategy for writing my code.
Thanks either way to both 😄

@Joakker Joakker closed this as completed Jan 1, 2025
@CppCXY
Copy link
Collaborator

CppCXY commented Jan 2, 2025

image

In the new language server preview, there is better support for generics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants