Recently, I was working on a TypeScript project that required creating a flexible way to store key-value pairs with type safety. The issue is… many developers struggle with properly typing objects in TypeScript.
In this article, I’ll cover everything you need to know about the TypeScript Record utility type, with practical examples that will make your code more robust and maintainable. So let’s dive in!
What is a TypeScript Record?
Record is a built-in utility type in TypeScript that helps you define an object type with specific key types and value types. It creates an object type whose property keys are Keys and property values are Type.
The syntax looks like this:
Record<Keys, Type>Where:
- Keys can be a union of string literals or a string/number/symbol
- Type can be any TypeScript type that you want your values to have
When to Use TypeScript Record
Below, I will explain some methods for using the TypeScript Record.
Method 1: Creating Objects with String Literal Keys
Let’s say we’re building a shopping application and want to store product prices:
type ProductNames = 'Ford' | 'Tesla' | 'Jeep';
type ProductPrices = Record<ProductNames, number>;
const prices: ProductPrices = {
Ford: 1.99,
Tesla: 0.99,
Jeep: 2.49
};
console.log("Product Prices:", prices);Now, TypeScript ensures that:
- You must include all the keys (‘Ford’, ‘Tesla’, ‘Jeep’)
- All values must be numbers
- You can’t add any extra keys that aren’t in the ProductNames type

Method 2: Using Broader Key Types
Sometimes we need more flexibility with our keys:
// An object with string keys and boolean values
const userPermissions: Record<string, boolean> = {
canEdit: true,
canDelete: false,
canCreate: true
};
// Add new permissions anytime
userPermissions.canPublish = true;
// Console log to display current permissions
console.log("User Permissions:", userPermissions);Since we used string as our key type, we can add any string key we want.

Method 3: Creating Dictionaries or Maps
The record is perfect for dictionary-like structures:
type UserId = string;
type UserData = { name: string; email: string; lastLogin: Date };
const userDatabase: Record<UserId, UserData> = {
'user_123': {
name: 'John Smith',
email: 'john@example.com',
lastLogin: new Date()
},
'user_456': {
name: 'Sarah Jones',
email: 'sarah@example.com',
lastLogin: new Date()
}
};This pattern is incredibly useful for any lookup table or cache.

Record vs. Interface vs. Type in TypeScript
When should you use Record instead of defining a regular interface or type alias? Here’s a quick comparison:
// Using Record
type UserRoles = Record<string, string[]>;
// Using interface
interface UserRoles {
[username: string]: string[];
}
// Using type with index signature
type UserRoles = {
[username: string]: string[];
};The main advantages of Record:
- It’s more concise and expressive
- It works great with mapped types and other type utilities
- It clearly communicates your intent to other developers
I use Record when I need a quick way to define a dictionary-like structure with consistent value types.
Advanced Usage of Records in TypeScript
Method 4: Combining with Other Utility Types
Record becomes really powerful when combined with other TypeScript utility types:
type User = {
id: number;
name: string;
email: string;
isAdmin: boolean;
};
// Create a record of users with only public information
type PublicUser = Pick<User, 'id' | 'name'>;
const userDirectory: Record<number, PublicUser> = {
1: { id: 1, name: 'John Smith' },
2: { id: 2, name: 'Jane Doe' }
};
// Console log to display the user directory
console.log("User Directory:", userDirectory);
Method 5: Using a Record for API Responses in TypeScript
When working with APIs, I often use Record to type responses that return collections:
type ApiResponse<T> = {
data: T;
status: number;
message: string;
};
// For a single user
type UserResponse = ApiResponse<User>;
// For a collection of users
type UsersResponse = ApiResponse<Record<string, User>>;
// Example response
const response: UsersResponse = {
data: {
'user_1': { id: 1, name: 'John', email: 'john@example.com', isAdmin: false },
'user_2': { id: 2, name: 'Jane', email: 'jane@example.com', isAdmin: true }
},
status: 200,
message: 'Success'
};
Real-World Examples in TypeScript Record
State Management in TypeScript
The record is excellent for state management in React applications:
type FormState = Record<string, string | boolean | number>;
const initialState: FormState = {
name: '',
email: '',
age: 0,
subscribe: false
};
function updateForm(state: FormState, field: string, value: string | boolean | number): FormState {
return {
...state,
[field]: value
};
}
// Update form state example
const updatedState = updateForm(initialState, 'name', 'John Doe');
// Console log to display initial and updated form states
console.log("Initial Form State:", initialState);
console.log("Updated Form State:", updatedState);
Best Practices When Using Record
- Be specific with key types when possible, use string literal unions instead of string when you know all possible keys.
- Consider read-only records for immutability
type ReadOnlyConfig = Readonly<Record<string, string>>;- Use with caution for empty objects
// This allows any property
const obj: Record<string, unknown> = {};
// This is more specific and safer
const obj: Record<'id' | 'name', string> = { id: '1', name: 'John' };Conclusion
I hope you found this article helpful! The TypeScript Record utility type is one of those features that seems simple at first but becomes increasingly valuable as your projects grow in complexity.
It helps you maintain type safety when working with dynamic objects and key-value collections, which is essential for building robust applications.
Other TypeScript articles you may also like:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.