Key of generic types

If I have a function with a generic type, could I make one of the arguments a dictionary that only allow the same keys as the provided type without requiring every key in the provided type?

I don’t think Luau natively supports this functionality, but you might be able to implement that on your own:

local function getKeys(dictionary): {string}
  local keys = {}
  for key, _ in pairs(dictionary) do
    if type(key) ~= “string” then continue end
    table.insert(keys, key)
  end

  return keys
end

local function verifyDictionaryKeys(generic, dictionary): boolean
  local dictKeys = getKeys(dictionary)
  for _, key in ipairs(dictKeys) do
    if generic[key] == nil then
      return false
    end
  end
end

local function genericFunction(generic, dictionary)
  if not verifyDictionaryKeys(generic, dictionary) then return end
  -- the rest of your code
end

i was hoping for a way to do it with types so it’d work with autocomplete but if that doesn’t exist i’ll just settle for this

1 Like

After going through the Type checking - Luau (luau-lang.org) page, I found that you can do this to make it work with types:

local function getKeys(dictionary: {[string]: any}): {string}
  local keys = {}
  for key, _ in pairs(dictionary) do
    table.insert(keys, key)
  end

  return keys
end

local function verifyDictionaryKeys<T>(generic: T, dictionary: {[string]: any}): boolean
  local dictKeys = getKeys(dictionary)
  for _, key in ipairs(dictKeys) do
    if generic[key] == nil then
      return false
    end
  end
end

local function genericFunction<T>(generic: T, dictionary: {[string]: any})
  if not verifyDictionaryKeys(generic, dictionary) then return end
  -- the rest of your code
end

will that be of any help?

I’m not too sure what you’re asking as it’s very vague (an example would be nice). However, if you’re talking about a function that automatically infers types in dictionaries, you can do something like this:

--> dictionary with value of generic type "T" that returns the same generic type
local function foo<T>(dict: {[string]: T}) -> T
    return next(dict) --> return the first available item in the dictionary
end

local autocompletedString = foo({a = "1", b = "2"}) --> intellisense will infer the variable as a string
local autocompletedNumber = foo({a = 1, b = 2}) --> intellisense will infer the variable as a number