Index Signatures
Part of the Introduction To Luau section of Coddy's Lua journey — lesson 72 of 73.
You met map types like {[string]: number} back in the tables chapter — an index signature: any string key maps to a number value. They shine when the keys aren't known while you write the code: counters, settings, caches, scores — anything built up at runtime.
type Counts = {[string]: number}
local counts: Counts = {}
counts["potion"] = 3 -- any string key is allowed
counts["sword"] = 1
counts["potion"] += 1 -- values are checked as numbersTwo runtime facts matter when working with maps. First, reading a key that was never set returns nil — the classic counting pattern handles that with or, turning "missing" into 0:
counts[item] = (counts[item] or 0) + 1Second, pairs() iterates a map's keys in no guaranteed order — running the same program twice can visit keys differently. Whenever output must be predictable, collect the keys into an array, table.sort them, and iterate the sorted array instead:
local keys: {string} = {}
for key in pairs(counts) do
table.insert(keys, key)
end
table.sort(keys)
for _, key in ipairs(keys) do
print(`{key}: {counts[key]}`)
endChallenge
EasyCount loot drops with a typed map.
- Declare
type Counts = {[string]: number}. - Write
countItems(items: {string}): Countsthat builds a freshCountsmap, counting how many times each string appears (use the(counts[item] or 0) + 1pattern). - Create
local loot: {string} = {"potion", "sword", "potion", "shield", "potion", "sword"}and count it. - Print one
[name]: [count]line per distinct item, in alphabetical order: collect the keys,table.sortthem, then print.
Expected output:
potion: 3
shield: 1
sword: 2Try it yourself
-- Write code here
-- 1) type Counts = {[string]: number}
-- 2) countItems(items: {string}): Counts using (counts[item] or 0) + 1
-- 3) count the loot array from the task
-- 4) collect keys, table.sort them, print `{name}: {count}` lines
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Introduction To Luau
1Getting Started with Luau
What Is Luau?Why Use Luau?Your First Luau CodeType Checking & Error ModesRecap: Introduction to Luau4Working with Functions
Typing Params & Return ValuesTyping Anonymous FunctionsFunctions Returning NothingOptional ParametersDefault Parameter ValuesVariadic FunctionsDefining Function TypesRecap: Typed Functions2Core Types
Basic Types: num, str, boolThe 'any' Type: Escape HatchThe 'unknown' TypeNil & Optional TypesType Inference in ActionExplicit Type AnnotationsRecap: Core Types Practice5Aliases, Unions, Intersections
Type Aliases for PrimitivesUnion TypesWorking with Union TypesLiteral TypesIntersection TypesCombining Type AliasesRecap: Advanced Type Combos8Enums, the Luau Way
The Enum Pattern in LuauNumeric Enums with TablesString Enums as UnionsUsing Literal Union EnumsFreezing Constant TablesRecap: Enums, the Luau Way11Advanced Topics
Type AssertionsType Guards With typeofThe never TypeNil Safety In Strict ModeIndex SignaturesRecap: Fine-Tuning Types3Typed Tables: Arrays & Maps
Typed ArraysAdding and Reading ElementsWhat is a Map Type?Declaring and Accessing MapsIterating TablesMixed-Shape TablesMulti-dimensional Typed Arraystable.unpack and VarargsRecap: Arrays and Maps