Last updated: Feb 27, 2024
Reading timeยท3 min
Use a generic to type the reduce()
method in TypeScript. The generic is used
to specify the type of the return and the initial values of the reduce()
method.
const arr = [{ id: 1 }, { name: 'bobby hadz' }, { salary: 100 }]; type ReduceReturnType = { id?: number; name?: string; salary?: number; }; const result = arr.reduce<ReduceReturnType>( (accumulator, current) => { return { ...accumulator, ...current }; }, {}, // ๐๏ธ initial value ); // const result: ReduceReturnType console.log(result); // ๐๏ธ {id: 1, name: 'bobby hadz', salary: 100} console.log(result.id); // ๐๏ธ 1 console.log(result.name); // ๐๏ธ "bobby hadz" console.log(result.salary); // ๐๏ธ 100
We used a generic to specify the type of
the initial and return values of the Array.reduce()
method.
The type of the result
variable is ReduceReturnType
in the example.
We marked the properties in ReduceReturnType
as
optional
to satisfy the compiler because the initial value we passed to the reduce()
method is an empty object and isn't compatible with ReduceReturnType
.
You can also use a type assertion, especially if the type of the return value is different than the type of the initial value.
const arr = [{ id: 1 }, { name: 'Bobby Hadz' }, { salary: 100 }]; type ReduceReturnType = { id: number; // ๐๏ธ ๐๏ธ ๐๏ธ no longer optional name: string; salary: number; }; const result = arr.reduce<ReduceReturnType>( (accumulator, current) => { return { ...accumulator, ...current }; }, {} as ReduceReturnType, // ๐๏ธ ๐๏ธ ๐๏ธ Now using Type Assertion ); // const result: ReduceReturnType console.log(result); // ๐๏ธ {id: 1, name: 'Bobby Hadz', salary: 100} console.log(result.id); // ๐๏ธ 1 console.log(result.name); // ๐๏ธ "Bobby Hadz" console.log(result.salary); // ๐๏ธ 100
The function we passed to the reduce() method gets called for each element in the array.
The reduce()
method returns the accumulated result.
accumulator
variable.reduce(function(accumulator, current, index), initial_value)
The value we return from the callback function gets passed as the accumulator
on the next iteration.
reduce()
TypeScript might be able to infer the type of the reduce()
method and its
return type based on the type
of your initial value.
const employees = [{ salary: 100 }, { salary: 200 }, { salary: 300 }]; const result = employees.reduce((accumulator, current) => { return accumulator + current.salary; }, 0); // const result: number console.log(result); // ๐๏ธ 600
We passed a number as the initial value to the reduce()
method and returned a
number from the method, so TypeScript is able to infer the correct type.
Let's look at another example of typing the reduce()
method.
const arr = ['a', 'b', 'c']; type ReduceReturnType = Record<string, string>; const result = arr.reduce<ReduceReturnType>( (accumulator, current) => { return { ...accumulator, [current]: current }; }, {}, // ๐๏ธ initial value ); // const result: ReduceReturnType console.log(result); // ๐๏ธ {a: 'a', b: 'b', c: 'c'}
We used Record<string, string>
for the type of the accumulator
, initial
value and return value of the reduce()
method.
The Record<Keys, Type>
type is a
utility type
and is used to construct an object whose keys and values are of a specific type.
string
.In other words, the accumulator
variable in the example is an object that
contains string keys and values.
The current
variable stores the array element of the current iteration.
You can learn more about the related topics by checking out the following tutorials: