LuaLS / LuaLS/lua-language-server

Feature Request: Capture table keys similar to capturing generic types

Open
#2,058 1 comment 12 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Lua
Stars
4.4k
Forks
442
PR merge metrics
No merged PRs in 30d

Description

I like TypeScript's keyof operator that basically suggests that the value of a given string must match one of the properties/keys of a specified object.

In Lua, a type declared as @type keyof queries would mean it is a string whose value is a key found in the queries table.

This is useful because I can change just the value types if the keys of a table parameter were to be captured and specified as the target for a returned table type.

Here's an example of what I currently have to show the problem:

---@param queries table<string, string>
---@return table<string, QueryResult?>
local function QueryMany(queries)
  local results = {}

  for key, query in pairs(queries) do
    results[key] = Query(query) -- this function returns `QueryResult?`
  end

  return results
end

So, you can see that the queries argument is a table, and the keys should be exactly the same in the returned table, but only the values change.

Therefore, when I hover over the returned table in VS Code it doesn't know the keys in the table and only shows the key as being a string.

In the example above, the new annotation would look like this:

---@param queries table<string, string>
---@return table<keyof queries, QueryResult?>

Currently, I need to create custom aliases or cast the returned tables manually when using the QueryMany example function to add the desired intelli-sense in VS Code. This is a problem because the function is designed to be dynamically reusable with arbitrary table arguments.

For context, this is how I would use the above function:

local results = QueryMany({
  xSpacing = "frame.dimensions.xSpacing",
  ySpacing = "frame.dimensions.ySpacing",
  vDirection = "frame.behavior.vDirection",
  hDirection = "frame.behavior.hDirection",
})

(in summary: the table is transformed from a key-value pair of string/string to string/QueryResult? and there is no way of telling LuaLS this without losing the field/key names)

You could also support keyof for standard aliases and types:

---@type keyof queries
local queryName = "" -- the value of queryName must match a field key found in the queries table

-- or as an alias:
---@alias QueryName keyof queries

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository files, tests, or entry points are named in the issue. Start by locating the existing generic-type capture and annotation handling, then trace how table keys and aliases are represented. Done means keyof queries preserves the input table's keys for returned tables and validates standalone values or aliases against those keys.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.