How to Enforce the type of the indexed members of a Typescript object


The programming language TypeScript is based on JavaScript and is strongly typed, object-oriented, and compiled. The language is improved with tools like static typing, classes, and interfaces that help with early error detection and make JavaScript more manageable. One of TypeScript's features is the ability to enforce the types of an object's indexed members, and this process is also referred to as an index signature.

An index signature is a set of key-value pairs describing the many properties an object may have. The type of the property name and the type of the property value are specified, respectively, using the value and the key. To enforce the kinds of an object's properties, the user can utilize TypeScript's index signature feature.

Index signatures can effectively enforce certain object attributes, but they can also make the code challenging to comprehend and maintain. Therefore, it is essential only to employ index signatures when necessary.

Syntax

let objectName: {
   [key: string]: string
}

In the above syntax, ‘objectName’ is the name of our object, and we enforced the key types as a string and the values as a string.

Example 1

In this example, we have two interfaces, Person and PhoneBook. The Person interface defines the structure of a person object with two properties: name (string) and age (number). The PhoneBook interface defines an index signature that uses the string type as the key and the Person interface as the value. This means that any object that implements the PhoneBook interface can only have properties with keys of type string and values of type Person.

We then define a variable phoneBook type PhoneBook and assign an empty object. We then add some entries to the phone book, which should have the name as the key and the Person object as the value. Finally, we console log the values to verify if we tried to put any other type of variable instead of the mentioned types, and then the compiler will give an error.

// Person interface
interface Person {
   name: string
   age: number
}

// PhoneBook interface
interface PhoneBook {
   [key: string]: Person
}

let phoneBook: PhoneBook = {}

phoneBook['Person 1'] = { name: 'ABC', age: 30 }
phoneBook['Person 2'] = { name: 'XYZ', age: 25 }
phoneBook['Person 3'] = { name: 'MNO', age: 10 }

console.log(phoneBook)

On compiling, it will generate the following JavaScript code −

var phoneBook = {};
phoneBook['Person 1'] = { name: 'ABC', age: 30 };
phoneBook['Person 2'] = { name: 'XYZ', age: 25 };
phoneBook['Person 3'] = { name: 'MNO', age: 10 };
console.log(phoneBook);

Output 

The above code will produce the following output –

{ 'Person 1': { name: 'ABC', age: 30 },
  'Person 2': { name: 'XYZ', age: 25 },
  'Person 3': { name: 'MNO', age: 10 } }

Example 2

In this example, we have an interface Product that defines the structure of a product object with two properties: name (string) and price (number). Then we have another interface ShoppingCart that represents an index signature that uses the number type as the key and the Product interface as the value. Any object that implements the ShoppingCart interface can only have properties with keys of type number and values of type Product.

We then define a variable cart of the type ShoppingCart and assign an empty object to it. We then add some entries to the cart, which should have the product id as the key and the product object as the value. We can see that the entries are correctly added to the cart, which will give an error if the value is not of Product type or if the product object is missing any of the properties defined in the Product interface.

interface Product {
   name: string
   price: number
}

// ShoppingCart interface
interface ShoppingCart {
   [key: number]: Product
}

let cart: ShoppingCart = {}

cart[1] = { name: 'Shirt', price: 20 }
cart[2] = { name: 'Pants', price: 30 }
cart[3] = { name: 'Shoes', price: 40 }

console.log(cart[1])
console.log(cart[2])
console.log(cart[3])

On compiling, it will generate the following JavaScript code −

var cart = {};
cart[1] = { name: 'Shirt', price: 20 };
cart[2] = { name: 'Pants', price: 30 };
cart[3] = { name: 'Shoes', price: 40 };
console.log(cart[1]);
console.log(cart[2]);
console.log(cart[3]);

Output 

The above code will produce the following output –

{ name: 'Shirt', price: 20 }
{ name: 'Pants', price: 30 }
{ name: 'Shoes', price: 40 }

These examples illustrate how to index signatures can be used to enforce the types of properties of an object. Index signatures are a powerful feature that can help you write more robust and maintainable code, but it's important to use them judiciously and only when necessary.

Updated on: 21-Feb-2023

474 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements