Skip to content

Local reference to enum defined in an object from a different file, same workspace #3328

Closed

Description

@erunehtar

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?

Diagnostics/Syntax Checking

Expected Behaviour

file1.lua

local module = ...

---@enum Module.Color
module.Color = {
    White = "ffffffff",
    Black = "ff000000",
    Yellow = etc...
}

file2.lua

local module = ...

---@type Module.Color
local Color = module.Color

---@param color Module.Color
local function SetColor(color)
    -- code ...
end

---@param text string
local function Print(text)
    SetColor(Color.Blue) -- no diagnostic errors
end

Actual Behaviour

file1.lua

local module = ...

---@enum Module.Color
module.Color = {
    White = "ffffffff",
    Black = "ff000000",
    Yellow = etc...
}

file2.lua

local module = ...

---@type Module.Color
local Color = module.Color

---@param color Module.Color
local function SetColor(color)
    -- code ...
end

---@param text string
local function Print(text)
    SetColor(Color.Blue) -- Undefined field `Blue`. Lua Diagnostics.(undefined-field)
end

Reproduction steps

Simply make a local reference to an enum defined in a table, try to use it.

Additional Notes

I want to share an enum across lua files and have a reference on it so that I can type Color.Blue instead of module.Color.Blue. Lua allows me to have a local reference, doing local Color = module.Color compile and works just fine, but the diagnostic is not happy, marking the local reference as ---@type Module.Color doesn't seem enough.

I feel like I might be doing this wrong, is there a syntax to achieve what I am trying to do? I cannot put the enum Color in global space, I have to put it in the module object, so that it does not clash with other modules.

Log File

No response

Activity

  1. erunehtar commented on Jan 9, 2026

    @erunehtar
    Author

    I was able to workaround it by doing:

    file1.lua

    local module = ...
    
    ---@alias Module.Color string
    ---@alias Module.ColorEnum table<string, Module.Color>
    
    ---@type Module.ColorEnum
    module.Color = {
        White = "ffffffff",
        Black = "ff000000",
        Yellow = etc...
    }

    file2.lua

    local module = ...
    
    ---@type Module.ColorEnum
    local Color = module.Color

    Basically, skip using @enum and make up a custom enum declaration. However this lose the enum validation, since now using ---@param Module.Color allows for any string to be passed to the function.

    Please let me know if this can be achieved using @enum with some syntax I could not figure out.

  2. tomlau10 commented on Jan 10, 2026

    @tomlau10
    Contributor

    I believe you misused the @enum.
    please see #3151 (comment)


    And if your module.lua already return that module table, you actually don't need @type at all 🤔

    • module.lua
    local module = {}
    
    ---@enum Module.Color
    module.Color = {
        White = "ffffffff",
        Black = "ff000000",
    }
    
    return module
    • main.lua
    local module = require "module"
    
    -- the server already know the type of `module.Color`
    local Color = module.Color
    
    print(Color.Black)
    print(Color.NoSuchColor) --<< warning: undefined field
    Image
  3. erunehtar commented on Jan 10, 2026

    @erunehtar
    Author

    Sorry I forgot to mention that there is no return module nor require "module" in my Lua environment (this is WoW Lua 5.1 environment), and the way the "module" object is passed around is by providing it as an argument when they load the lua file, we get the "module" by fetching it with local moduleName, module = ... at the top of each lua file of the project.

    Would this environment cause issues with how the Lua language server process types across units?

    But in any case, that comment you posted indeed contained the solution to my issue! And I don't even need the ---@type anymore in file2.lua, which is even better. ❤️ thank you very much!

    Here is the full working syntax if anyone ever search for this again (the key was really the ---@class and .* combinaison) :

    file1.lua

    local moduleName, module = ... ---@cast module Module
    
    ---@class Module
    ---@field Color Module.Color.*
    
    ---@enum Module.Color
    local Color = { ---@class Module.Color.*
        White = "ffffffff",
        Black = "ff000000",
        Yellow = etc...
    }
    module.Color = Color

    file2.lua

    local moduleName, module = ... ---@cast module Module
    
    local Color = module.Color
    
    ---@param color Module.Color
    local function SetColor(color)
        -- code ...
    end
    
    ---@param text string
    local function Print(text)
        SetColor(Color.Blue) -- no diagnostic errors, yay! =D
    end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions