DEV Community

Andrew Lee
Andrew Lee

Posted on

TypeScript Onboarding for React Engineers

We can get started with TypeScript right away as React engineers. As long as we know how to type props to our components and write handlers for our events, we can build most of our UI in TypeScript.

Create app with TypeScript

npx create-react-app todo --template typescript
Enter fullscreen mode Exit fullscreen mode

Code

import React, { useState } from 'react';

const TodoApp = () => {
  // <Array<string>> specifies state will be Array<string>
  // Generics: https://www.typescriptlang.org/docs/handbook/generics.html
  const [todos, setTodos] = useState<Array<string>>([]);
  const [newTodo, setNewTodo] = useState('');

  const onAdd = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setTodos([...todos, newTodo]);
    setNewTodo('');
  };

  const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setNewTodo(event.target.value);
  };

  const onRemove = (todo: string) => {
    setTodos(todos.filter((t) => t !== todo));
  };

  return (
    <>
      {todos.map((todo) => (
        <TodoItem todo={todo} onRemove={onRemove} />
      ))}
      <form onSubmit={onAdd}>
        <input type="text" onChange={onChange} value={newTodo} />
      </form>
    </>
  );
}

// Specify prop types with interface
interface TodoItemProps {
  // We can specify values
  // Basic types: https://www.typescriptlang.org/docs/handbook/basic-types.html
  todo: string;
  // as well as functions
  onRemove(todo: string): void;
  // and other interfaces/types if we wanted too
}

// We are typing function argument `props`
// Object destructuring
const TodoItem = ({ todo, onRemove }: TodoItemProps) => {
  return (
    <div onClick={() => onRemove(todo)} role="button">{todo}</div>
  );
};

export default TodoApp
Enter fullscreen mode Exit fullscreen mode

Interfaces

Interfaces are used to describe a structure of an object.

interface TodoItemProps {
  todo: string;
  onRemove(todo: string): void;
}
Enter fullscreen mode Exit fullscreen mode

Once an interface is defined, we can use it with a component:

const TodoItem = ({ todo, onRemove }: TodoItemProps) => {
  return (
    <div onClick={() => onRemove(todo)} role="button">{todo}</div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Learn more about interfaces:
https://www.typescriptlang.org/docs/handbook/interfaces.html

Event Handlers

Event handlers are functions and TypeScript allows us to specify the type of the argument.

For forms we can use React.FormEvent<HTMLFormElement>:

const onAdd = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  setTodos([...todos, newTodo]);
  setNewTodo('');
};
Enter fullscreen mode Exit fullscreen mode

For input change we can use React.ChangeEvent<HTMLInputElement>:

const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  setNewTodo(event.target.value);
};
Enter fullscreen mode Exit fullscreen mode

These types are provided by @types/react. We can see what other types are available here:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts

Learn more about functions in TypeScript:
https://www.typescriptlang.org/docs/handbook/functions.html

Top comments (0)