Skip to content

How to properly annotate lazy-loaded sub-modules? #3241

@Bekaboo

Description

@Bekaboo

Say, I have a module called utils inside which I have sub-modules utils.fs,
utils.str and utils.web:

utils
├── init.lua
├── fs.lua
├── str.lua
└── web.lua

I want to be able to require only the utils module and be able to access
the sub-modules as if they are fields of the utils module, i.e.

local utils = require('utils')

utils.fs.fs_helper_fun(...)
utils.str.str_helper_fun(...)
utils.web.web_helper_fun(...)

But I don't want to load the sub-modules at once on requiring the utils
module, instead, they should only be loaded when needed, so in utils/init.lua
I have:

return setmetatable({}, {
  __index = function(_, key)
    return require('utils.' .. key)
  end,
})

But this confuses LuaLS and it does not provide any completion for sub-modules,
e.g. utils.fs, utils.str, etc.

I am aware that there is ---@module, I tried with

return setmetatable({
  fs = {} ---@module 'utils.fs'
  str = {} ---@module 'utils.str'
  web = {} ---@module 'utils.web'
}, {
  __index = function(_, key)
    return require('utils.' .. key)
  end,
})

with no luck.

Is there a way to make LuaLS aware of the sub-modules when I index to utils?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions