Open In App

How to Define Strongly Type Nested Object Keys with Generics in TypeScript ?

Last Updated : 19 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

We will look into the effective use of generics in TypeScript to ensure type safety when working with nested objects. By employing generics, developers can establish strongly typed keys for nested objects, significantly reducing the likelihood of runtime errors and enhancing code maintainability.

Approach 1: Using Recursive Generics

This approach employs recursive generics to define a type, NestedObject<T>, representing nested objects. It iterates over each property K of the input type T. If the property’s value is an object, it recursively applies the NestedObject type to ensure type safety for nested objects. Otherwise, it assigns the original type. This approach provides an intuitive way to enforce strong typing for nested object keys.

Syntax:

type NestedObject<T> = {
[K in keyof T]: T[K] extends object ? NestedObject<T[K]> : T[K];
};

Example: This example shows the use of the above-explained approach.

Javascript




// Define a generic type for nested objects
type NestedObject<T> = {
    [K in keyof T]: T[K] extends object ?
    NestedObject<T[K]> : T[K];
};
 
// Define a nested object type
type User = {
    id: number;
    name: string;
    address: {
        city: string;
        zip: number;
    };
};
 
// Utilize NestedObject type to
// create a strongly typed nested object
type TypedUser = NestedObject<User>;
 
// Usage
const user: TypedUser = {
    id: 1,
    name: "John Doe",
    address: {
        city: "New York",
        zip: 12345,
    },
};
 
console.log(user.address.city);


Output:

New York

Approach 2: Using Conditional Types

In this approach, we utilize conditional types to define the NestedObject<T> type. It checks if the input type T extends object. If so, it iterates over each property K of T and applies the NestedObject type recursively. Otherwise, it assigns the original type. This approach provides another way to achieve strong typing for nested object keys, offering flexibility in type definitions.

Example: This example shows the use of the above-explained approach.

Javascript




// Define a generic type for nested
// objects using conditional types
type NestedObject<T> = T extends object ?
    { [K in keyof T]: NestedObject<T[K]> } : T;
 
// Define a nested object type
type Product = {
    id: number;
    name: string;
    details: {
        price: number;
        description: string;
    };
};
 
// Utilize NestedObject type to
// create a strongly typed nested object
type TypedProduct = NestedObject<Product>;
 
// Usage
const product: TypedProduct = {
    id: 1,
    name: "Laptop",
    details: {
        price: 99999,
        description:
            "High-performance laptop with SSD storage",
    },
};
 
console.log(product.details.price);


Output:

99999


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads