Defining and using Key-Value pair in TypeScript

avatar

Borislav Hadzhiev

Last updated: Feb 27, 2022

banner

Photo from Unsplash

Defining and using key-value pair in TypeScript #

Use an index signature to define a key-value pair in TypeScript, e.g. const employee: { [key: string]: string | number } = {}. An index signature is used when we don't know all the names of a type's keys ahead of time, but we know the shape of their values.

index.ts
const employee: { [key: string]: string | number } = {}; employee.name = 'James'; employee.salary = 100; // 👇️ {name: 'James', salary: 100} console.log(employee);

We used an index signature to define a key-value pair in TypeScript;.

The {[key: string]: string} syntax is an index signature in TypeScript and is used when we don't know all the names of a type's properties ahead of time, but know the shape of the values.

The index signature in the examples means that when an the object is indexed with a string, it will return a value of type string or number.

You might also see the index signature {[key: string]: any} in examples. It represents a key-value structure that when indexed with a string returns a value of any type (very broad).

index.ts
const employee: { [key: string]: any } = {}; employee.name = 'James'; employee.salary = 100; employee.years = [2021, 2022]; // 👇️ {name: 'James', salary: 100, years: [2021, 2022]} console.log(employee);

The {[key: string]: any} index signature is used to create a key-value pair when we don't know the names of a type's keys and the shape of the values ahead of time.

You can declare the types of the keys and values that you know ahead of time and use an any type for the ones you don't.

index.ts
type Employee = { [key: string]: any; name: string; salary: number; }; const employee: Employee = { name: 'James', salary: 100, }; employee.country = 'Chile'; employee.years = [2021, 2022];

We declared types for the name and salary properties, which we know about ahead of time and used an index signature to still allow us to assign any key with any value to the object.

This is useful, because we still get type support for the name and salary properties and the type checker would throw an error if we try to set the properties to an incompatible type.

If you try to assign a property of an incompatible type to the object, you'd get an error.

index.ts
type Employee = { [key: string]: string; }; const employee: Employee = { name: 'James', }; // ⛔️ Type 'number' is not assignable // to type 'string'.ts(2322) employee.salary = 100;

We used an index signature with string keys and values, so the type checker shows an error if we try to add a number value to the object.

However, we can't simply add a salary key that has a type of number to Employee, because we've already specified that all keys of type string have a value of string.

The index signature {[key: string]: string} means that when the object is indexed with a key that's a string, the value is always going to be a string.

index.ts
type Employee = { [key: string]: string; // ⛔️ Error: Property 'salary' of type 'number' // is not assignable to 'string' index type 'string'. salary: number; };

To get around this, you have to use a union type.

index.ts
type Employee = { [key: string]: string | number; salary: number; }; const employee: Employee = { name: 'James', salary: 100, };

The new index signature means that if the object is indexed with a string key, it returns a value that is a string or number, so we are able to set other properties on the type that have a number value.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.