🔷 TypeScript Q18 / 101

What is Record type?

AI-Powered Answer ✓ Answered

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

typescript
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.

typescript
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.

typescript
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.

typescript
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.