I'm doing some maintenance in my NeoVim config, almost entirely written in Lua.
For convenience, I created a mini-lib of useful tools to ease this configuration.
I have several friends who keep a close eye on my NeoVim config, or even using it, and for that reason I like my toolings to be well documented to ease their experience with it.
Coming mainly from a TypeScript background, you can imagine that I like to go deep with it.
In this example, I have a module that reduces the hassle of setting up mappings, also making it more readable.
--- Set a keymap using Vim's API
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param mode MapModeStr The mode that your keymap will work in
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
local set = function(desc, mode, lhs, rhs, opts)
opts = opts or {}
local finalopts = vim.tbl_deep_extend("keep", { desc = desc }, opts)
vim.keymap.set(mode, lhs, rhs, finalopts)
end
return {
set = set,
--- Set a keymap for Insert mode
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
i = function(desc, lhs, rhs, opts) set(desc, "i", lhs, rhs, opts) end,
--- Set a keymap for Normal mode
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
n = function(desc, lhs, rhs, opts) set(desc, "n", lhs, rhs, opts) end,
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
o = function(desc, lhs, rhs, opts) end,
--- Set a keymap for Visual and Select mode
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
x = function(desc, lhs, rhs, opts) set(desc, "x", lhs, rhs, opts) end,
--- Set a keymap for Visual mode
---@param desc string The descritpion that will be shown for your mapping when calling :map
---@param lhs string A NeoVim keymap string
---@param rhs MapRHS The action yout keymap will trigger
---@param opts? MapOptions A table of options
v = function(desc, lhs, rhs, opts) set(desc, "v", lhs, rhs, opts) end,
}
To reduce copypasta, I would like to "typedef" the mapper functions that are exposed to my users in a meta file with the other types I've defined for this module. I know this is something I can do:
---@meta
...
---@alias MapperFunction fun(desc: string, lhs: string, rhs: MapRHS, opts: MapOptions?)
And then I could simply ---@type MapperFunction on them, but the issue then is that I lose the descriptions of what each parameter does, and I would like to avoid that.
The best I could come up with was some spicy little curry (functional programming rocks!). It works, but I wanted to know if there was a way to do it with only typings.

An annoying side effect is that I lose some of the completion annotations.

So, is there a way I could simply slap a type on top of my functions and retain all IntelliSense, or am I doomed to use one of those two techniques ?
Thanks!


I am not sure, if the below suggestion would be useful to you in your particular environment, but it may be interesting to Lua programmers in general.
It is a 'decorator' that allows to create Lua functions with typed arguments and returns. Function specification is a string, e.g.:
Nullable types (starting with
?) are allowed; so are multiple types, e.g.number|string.