Type useState as Array of Objects in React TypeScript

avatar

Borislav Hadzhiev

Last updated: Apr 20, 2022

banner

Photo from Unsplash

Type useState as Array of Objects in React TypeScript #

To type the useState hook as an array of objects in React, use the hook's generic, e.g. const [employees, setEmployees] = useState<{salary: number; name: string}[]>([]). The state variable can be initialized to an empty array and will only accept objects of the specified type.

App.tsx
import {useState} from 'react'; const App = () => { // 👇️ const employees: {salary: number;name: string;}[] const [employees, setEmployees] = useState<{salary: number; name: string}[]>( [], ); return ( <div> <button onClick={() => setEmployees(prevEmployees => [ ...prevEmployees, {salary: 100, name: 'Bob'}, ]) } > Add employee </button> {employees.map((employee, index) => { return ( <div key={index}> <h2> salary: {employee.salary} / name: {employee.name} </h2> </div> ); })} </div> ); }; export default App;

We used a generic to type the useState hook correctly while initializing the hook with an empty array.

react typescript usestate array of objects

Had we not used the generic, e.g. useState<{salary: number; name: string}[]>([]) when typing the hook, the type of the state variable would be never[], in other words, an array that will never contain any elements.

You can also use a type alias or an interface if the call to the useState hook gets busy.

App.tsx
import {useState} from 'react'; type Employee = { salary: number; name: string; }; const App = () => { // 👇️ const employees: Employee[] const [employees, setEmployees] = useState<Employee[]>([]); return ( <div> <button onClick={() => setEmployees(prevEmployees => [ ...prevEmployees, {salary: 100, name: 'Bob'}, ]) } > Add employee </button> {employees.map((employee, index) => { return ( <div key={index}> <h2> salary: {employee.salary} / name: {employee.name} </h2> </div> ); })} </div> ); }; export default App;

We extracted the object type into a type alias and used it as Employee[] to type the useState hook.

If we try to add a value of a different type to the state array, we would get a type checking error.

App.tsx
import {useState} from 'react'; type Employee = { salary: number; name: string; }; const App = () => { // 👇️ const employees: Employee[] const [employees, setEmployees] = useState<Employee[]>([]); // ⛔️ Argument of type '(prevEmployees: Employee[]) => (string | Employee)[]' is not assignable to parameter of type 'SetStateAction<Employee[]>'. setEmployees(prevEmployees => [...prevEmployees, 'Hello world']); return ( <div> <button onClick={() => setEmployees(prevEmployees => [ ...prevEmployees, {salary: 100, name: 'Bob'}, ]) } > Add employee </button> {employees.map((employee, index) => { return ( <div key={index}> <h2> salary: {employee.salary} / name: {employee.name} </h2> </div> ); })} </div> ); }; export default App;

The example shows how trying to add a string to a state array that is typed as Employee[] causes the type checker to error out.

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.