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

Support generic table #3042

Open
ibachar opened this issue Jan 15, 2025 · 6 comments
Open

Support generic table #3042

ibachar opened this issue Jan 15, 2025 · 6 comments

Comments

@ibachar
Copy link

ibachar commented Jan 15, 2025

Hi,

Is it possible to create a generic table such that the returned type is the key as a type. For example:

---@class MyClass
local MyClass = {}

---@generic T
---@type table<'T', T>
local Classes = {}

local c = Classes["MyClass"]

In the above example, I expect c to have the type MyClass

@tomlau10
Copy link
Contributor

Is it possible to create a generic table such that the returned type is the key as a type.

is this a feature request?

If this is just a question, then I don't think it's possible. 🤔
The closest I can think of, is to use a function to capture the literal string, and return it as the type

---@class MyClass
local MyClass = {}

local Classes = {}

---@generic T
---@param className `T`
---@return T
function GetClass(className)
    return Classes[className]
end

local c = GetClass("MyClass") --> c: MyClass

ps:
for questions / q&a, please consider using the discussion: https://github.com/LuaLS/lua-language-server/discussions
issue page is for tracking bugs / incorrect behavior / etc. 😅

but if this is a feature request, then you may keep it open.
Though I don't think maintainers will have time to finish it, given that it has workarounds/alternatives, and not a serious bug either.

@CppCXY
Copy link
Collaborator

CppCXY commented Jan 15, 2025

image
I suggest you look this: #3017

@tomlau10
Copy link
Contributor

image I suggest you look this: #3017

I think this is different from what requested in this issue 😕

  • The author wants
    • Classes["MyClass"] => return MyClass
    • Classes["YourClass"] => return YourClass
  • But not a generic class that always return the template type
    • The example given in your reply is that MyClass<string> => every string index to it returns a string value

@CppCXY
Copy link
Collaborator

CppCXY commented Jan 15, 2025

I think this is different from what requested in this issue 😕

  • The author wants

    • Classes["MyClass"] => return MyClass
    • Classes["YourClass"] => return YourClass
  • But not a generic class that always return the template type

    • The example given in your reply is that MyClass<string> => every string index to it returns a string value

Ok, I have namespace type:
image

However, I don't have a global namespace. Adding this is not difficult.

@ibachar
Copy link
Author

ibachar commented Jan 16, 2025

@tomlau10 Yes this is a feature request. For now I've implemented it using a predefined set of types in the table

@tomlau10
Copy link
Contributor

tomlau10 commented Jan 16, 2025

For now I've implemented it using a predefined set of types in the table

Yeah~ I almost forget that you can have a class and define the fields of it.
But as you might guess, need to update it every time you add a new class, so quite troublesome 🙁

---@class MyClass
local MyClass = {}

---@class YourClass
local YourClass = {}

---@class Classes
---@field MyClass MyClass
---@field YourClass YourClass
local Classes = {}

local c1 = Classes["MyClass"]   --> c1: MyClass
local c2 = Classes["YourClass"] --> c2: YourClass
local c3 = Classes["HisClass"]  --> c3: unknown

An improved version

luals supports C# partial class define style.
You can add @field to the same class in different parts of your code, so no need to write them all at once.
=> you can break up those @class definition

  • Classes.lua
---@class Classes
local Classes = {}

return Classes
  • MyClass.lua
---@class MyClass
local MyClass = {}

---@class Classes
---@field MyClass MyClass
-- luals now knows `Classes.MyClass` = MyClass type

return MyClass
  • YourClass.lua
---@class YourClass
local YourClass = {}

---@class Classes
---@field YourClass YourClass
-- luals now knows `Classes.YourClass` = YourClass type as well

return YourClass
  • main.lua
local Classes = require "Classes"

local c1 = Classes["MyClass"]   --> c1: MyClass
local c2 = Classes["YourClass"] --> c2: YourClass
local c3 = Classes["HisClass"]  --> c3: unknown

These workarounds might suit your need before this feature request is implemented.
Also maybe you would like to try CppCXY's language server, it has much better generic support. 😄

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