Syntax
Record<KeyType, ValueType>Examples
A Basic Record
Typing a dictionary object with a known key set.
type Role = "admin" | "editor" | "viewer";
const permissions: Record<Role, string[]> = {
admin: ["read", "write", "delete"],
editor: ["read", "write"],
viewer: ["read"]
};
// TypeScript ensures ALL three roles are present with the correct value type
console.log(permissions.admin); // ["read", "write", "delete"]Record with String Keys
A more open dictionary type, equivalent to an index signature but more concise.
const scores: Record<string, number> = {
alice: 95,
bob: 87,
charlie: 92
};
// Equivalent to writing:
// interface Scores { [name: string]: number; }Best practices
- Use Record<Keys, ValueType> as the concise, preferred way to type dictionary-style objects, rather than writing an index signature by hand
- Use a specific literal union for Keys (like Record<Role, string[]>) when you want TypeScript to enforce that every possible key is actually present
- Use Record<string, ValueType> for a genuinely open-ended dictionary where keys are not known ahead of time
- Prefer Map over Record when keys are added/removed dynamically at runtime - Record is best suited for a fixed, known shape
At a glance
- Purpose
- Static types for JavaScript
- File extension
- .ts ยท .tsx
- Runs in
- Compiled to JavaScript
- Usually used with
- JavaScript and its ecosystem
Specifications & further reading
Related TypeScript documentation
Partial<T> and Required<T>
Partial<T> constructs a new type with every property of T marked optional - useful for representing partial updates, like a PATCH request body. Required<T> does the opposite, making every property mandatory even if the original type had optional ones, useful for ensuring a fully-populated object at a specific point in your code.Pick<T> and Omit<T>
Pick<T, Keys> constructs a new type by selecting only the specified properties from T. Omit<T, Keys> does the reverse, constructing a new type with all properties of T except the specified ones. Both are extremely common for deriving smaller, focused types from a larger base type without duplicating the definition.Readonly<T>
Readonly<T> constructs a new type where every property of T is marked readonly, preventing reassignment after the object is created. It is a shallow transformation - nested objects within a Readonly<T> are not automatically deep-frozen, only the top-level properties are protected from reassignment.ReturnType<T> and Parameters<T>
ReturnType<T> extracts the return type of a function type, and Parameters<T> extracts its parameter types as a tuple. Both are especially useful for deriving types from functions you do not directly control, like third-party library functions, without manually duplicating their signatures.
Partial<T> constructs a new type with every property of T marked optional - useful for representing partial updates, like a PATCH request body. Required<T> does the opposite, making every property mandatory even if the original type had optional ones, useful for ensuring a fully-populated object at a specific point in your code.Pick<T> and Omit<T>
Pick<T, Keys> constructs a new type by selecting only the specified properties from T. Omit<T, Keys> does the reverse, constructing a new type with all properties of T except the specified ones. Both are extremely common for deriving smaller, focused types from a larger base type without duplicating the definition.Readonly<T>
Readonly<T> constructs a new type where every property of T is marked readonly, preventing reassignment after the object is created. It is a shallow transformation - nested objects within a Readonly<T> are not automatically deep-frozen, only the top-level properties are protected from reassignment.ReturnType<T> and Parameters<T>
ReturnType<T> extracts the return type of a function type, and Parameters<T> extracts its parameter types as a tuple. Both are especially useful for deriving types from functions you do not directly control, like third-party library functions, without manually duplicating their signatures.