> For the complete documentation index, see [llms.txt](https://wiki.nushackers.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.nushackers.org/orbital/typescript/typing-component-props-events-and-hooks.md).

# Typing Component Props, Events, and Hooks

**TypeScript** really shines in React when working with component props, events, and hooks like `useState` or `useEffect`. Here’s how to type them properly so you get type safety and helpful autocompletions.

## Typing Component Props

```tsx
interface Todo {
  title: string;
  done: boolean;
}

interface TodoItemProps {
  todo: Todo;
  onToggle: (title: string) => void;
}

const TodoItem: React.FC<TodoItemProps> = ({ todo, onToggle }) => (
  <div>
    <input
      type="checkbox"
      checked={todo.done}
      onChange={() => onToggle(todo.title)}
    />
    {todo.title}
  </div>
);
```

> #### 💡 Tip: Try it in your IDE!
>
> With typed props, you’ll get autocompletion and instant feedback — making mistakes harder and coding faster.

## Typing useState

### Step 1: Create the state type

```tsx
interface Todo {
  title: string;
  done: boolean;
}
```

### Step 2: Type the useState hook

```tsx
// empty initial state
const [todos, setTodos] = useState<Todo[]>([]);
```

```tsx
const INITIAL_TODO: Todo[] = [
  {
    title: "first task",
    done: false,
  },
  {
    title: "second task",
    done: true,
  },
  {
    title: "third task",
    done: true,
  },
];

const [todos, setTodos] = useState<Todo[]>(INITIAL_TODO);
```

Now `todos` is typed as an array of `Todo` objects, and `setTodos` will only accept that type.

### Step 3: Using setTodos

Here are three valid and clean ways to use `setTodos`:

```tsx
// 1. Basic usage — straightforward and readable
setTodos([{ title: "new todo", done: false }]);

// 2. Callback form — preferred if referencing previous state or writing multiple lines
setTodos((prevTodos) => {
  return [...prevTodos, { title: "new todo", done: false }];
});

// 3. One-liner callback — clean if short
setTodos((prev) => [...prev, { title: "new todo", done: false }]);
```

> #### :brain: Why use the `callback` form?
>
> React batches updates — using the `callback` ensures you’re working with the **most recent state**, especially inside `useEffect` or async operations.

## Typing Events

React’s synthetic events are strongly typed too. Here’s an example with an input change handler:

```tsx
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  console.log(e.target.value);
};
```

## Typing Custom Hooks

If you create your own hooks, type the input and output clearly:

```tsx
function useTodoList(): [Todo[], (todo: Todo) => void] {
  const [todos, setTodos] = useState<Todo[]>([]);

  const addTodo = (todo: Todo) => setTodos((prev) => [...prev, todo]);

  return [todos, addTodo];
}
```

```tsx
const [todos, addTodo] = useTodoList();
addTodo({ title: "Learn TS", done: false });
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wiki.nushackers.org/orbital/typescript/typing-component-props-events-and-hooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
