TypeScript Dictionary: A Complete Guide with Practical Examples
Implementing associative arrays or "dictionaries" is a daily task for web engineers. In 2026, TypeScript offers more robust, type-safe ways to handle these structures than ever before.
What is a Dictionary in TypeScript?
In computer science, a dictionary is a collection of keys and values, where each key is unique and mapped to a specific value. In JavaScript, we traditionally use objects to achieve this. However, in TypeScript, we need to ensure that our dictionary is type-safe. This means the compiler should know what types of keys are allowed and what type of value we expect back when we access one.
For example, the PrimeIcons list is fundamentally structured as a dictionary mapping icon names (strings) to metadata. Understanding how to model this effectively is key to professional application development.
Method 1: Using the Record Utility Type (Recommended)
The Record<K, T> utility type is the cleanest and most modern way to define a dictionary in TypeScript. It is highly readable and works perfectly with Union types to restrict keys.
Syntax and Basic Usage
Here is how you define a simple dictionary mapping string keys to numeric values (e.g., an inventory list):
"laptop": 15,
"monitors": 20,
"keyboards": 45
};
Advantages of Record<K, T>
Beyond basic string keys, Record shines when used with Union types. This prevents the addition of arbitrary keys that aren't defined in your business logic:
const pricing: Record<Category, number> = {
"software": 299,
"hardware": 599,
"service": 150
}; // Correct. Any other key will cause an error.
Method 2: Using Index Signatures in Interfaces
Index signatures are the classic way to define dictionaries. They are useful when you want to define a dictionary as part of a larger interface.
Defining String Keys
[id: string]: User;
}
const users: UserDictionary = {
"user_01": { name: "Alice", active: true },
"user_02": { name: "Bob", active: false }
};
Handling Optional Properties
A limitation of index signatures is that once defined, they force every other property in the interface to match that value type. This is why Record is often preferred for pure dictionary objects.
Method 3: Using the ES6 Map Object
Sometimes a plain object isn't enough. The ES6 Map object is a powerful alternative, especially when you need non-string keys or when you perform frequent insertions and deletions.
Map vs Object Performance
In 2026, browser engines have highly optimized the Map object. Unlike plain objects, Map preserves insertion order and doesn't have the risk of property collision with built-in prototypes like toString.
dictionary.set(1, "Value One");
dictionary.set(2, "Value Two");
console.log(dictionary.get(1)); // "Value One"
Iterating over a Map Dictionary
Maps are natively iterable, making them perfect for loops in UI frameworks like Angular.
Best Practices for TypeScript Dictionaries in 2026
As we move further into strict-type development, simply defining a dictionary isn't enough. You must consider how you consume it.
Type Safety and 'undefined' checks
In 2026, we strongly recommend enabling the noUncheckedIndexedAccess flag in your tsconfig.json. This forces you to handle cases where a key might not exist in the dictionary, returning T | undefined instead of just T.
const val = stock["monitor"]; // type is 'number | undefined'
if (val !== undefined) {
process(val);
}
Frequently Asked Questions about TypeScript Dictionaries
How do I declare a dictionary with string keys and numeric values?
The most modern approach is to use the Record<string, number> utility type. It provides the perfect balance of readability and safety for basic associative arrays.
What is the difference between a Map and a Record in TypeScript?
A Record is just a type for a plain JavaScript object, while a Map is a built-in collection type with its own methods (set, get, has). Use Map if you need high-performance dynamic sizing or non-string keys.
How to handle missing keys safely?
As discussed, enabling noUncheckedIndexedAccess is the gold standard for 2026 safety, ensuring you always check if a dictionary access returned undefined.