Borislav Hadzhiev
Sun Feb 27 2022·3 min read
Photo by Brooke Cagle
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.
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.
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).
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.
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.
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.
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
.
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.
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.