What is Record type?
The `Record` utility type in TypeScript is a powerful feature for constructing an object type with a specific set of keys and a uniform value type. It's particularly useful for creating dictionary-like objects or maps where you need strong typing for both the keys and their corresponding values.
What is Record<Keys, Type>?
Record<Keys, Type> is a TypeScript utility type that constructs an object type whose property keys are Keys and whose property values are Type. It allows you to define an object where every property (identified by a key from Keys) will have the same Type.
This utility is ideal for scenarios where you want to enforce that an object has a predefined set of string, number, or symbol keys, and all values associated with these keys adhere to a particular type.
Syntax
type MyObject = Record<Keys, Type>;
Parameters
Keys: A union of string, number, or symbol literal types, or a type that represents such keys (e.g.,string,keyof any). These will form the keys of the resulting object type.Type: The type that all property values of the resulting object will have.
Example Usage
Basic String Keys and Number Values
Define an object where keys are specific product names and values are their prices.
type ProductPrices = Record<'apple' | 'banana' | 'orange', number>;
const prices: ProductPrices = {
apple: 1.2,
banana: 0.8,
orange: 1.5
};
// Error: Property 'grape' does not exist on type 'ProductPrices'.
// const invalidPrices: ProductPrices = {
// apple: 1.2,
// grape: 2.0 // TS Error
// };
// Error: Type 'string' is not assignable to type 'number'.
// const wrongTypePrices: ProductPrices = {
// apple: 'free', // TS Error
// banana: 0.8,
// orange: 1.5
// };
Using Enums as Keys
Illustrate how to use an enum's values as the keys for your Record type.
enum UserRole {
Admin = 'admin',
Editor = 'editor',
Viewer = 'viewer'
}
type UserPermissions = Record<UserRole, boolean>;
const userAccess: UserPermissions = {
[UserRole.Admin]: true,
[UserRole.Editor]: true,
[UserRole.Viewer]: false
};
// Error: Property 'Moderator' does not exist on type 'UserPermissions'.
// const invalidAccess: UserPermissions = {
// admin: true,
// Moderator: false // TS Error
// };
Mapping to a Custom Type
Show how to map a set of keys to a more complex custom interface or type.
interface UserInfo {
name: string;
email: string;
isActive: boolean;
}
type UserDictionary = Record<string, UserInfo>;
const users: UserDictionary = {
'user1': { name: 'Alice', email: 'alice@example.com', isActive: true },
'user2': { name: 'Bob', email: 'bob@example.com', isActive: false }
};
console.log(users['user1'].name); // Output: Alice
When to use Record
- When you need to define an object where all keys are of a specific type (e.g., a union of string literals, or
string) and all values are of a consistent type. - For creating dictionary-like objects (maps) where you want strong typing for both the keys and their associated values.
- When working with configuration objects where all configuration items share the same data structure.
- As a more type-safe alternative to index signatures (
[key: string]: Type) when the exact set of keys is known or can be derived from a type like an enum or union.