JSX.Element, ReactNode, ReactElement: quando usar o quê em TypeScript?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

JSX.Element vs ReactNode vs ReactElement: A batalha de tipos que você precisa vencer



Olá, colega! Se você escreve em React com TypeScript, certamente já se deparou com uma situação em que o compilador começa a reclamar dos tipos de valores retornados. "Expected JSX.Element, got ReactNode" — um erro familiar? Ou talvez você tenha visto ReactElement em genéricos e se perguntado: "Qual é a diferença, afinal?"



Spoiler: não são apenas termos acadêmicos. A escolha correta do tipo pode acelerar seu código, prevenir bugs e tornar os componentes mais previsíveis. Hoje vamos analisar este tópico com exemplos reais, para que você nunca mais confunda esses três tipos. Vamos lá!



Breve introdução: o que é o quê



Vamos começar com o básico. Os três tipos fazem parte do mesmo ecossistema, mas com diferentes níveis de abstração.



ReactElement

Este é o bloco de construção fundamental. ReactElement é um objeto com tipo, props e chave. Ele representa o "projeto" do elemento que o React transformará em um nó DOM real. Se você escreve React.createElement('div', null, 'Hello'), obtém exatamente um ReactElement.



import React from 'react';

const element: React.ReactElement = React.createElement('div', { className: 'box' }, 'Olá!');// Tipo: ReactElement<{ className: string }, 'div'>


Importante: ReactElement é um genérico. Você pode especificar o tipo das props e o tipo do elemento:



type MyElement = React.ReactElement<{ name: string }, 'button'>;


JSX.Element

Esta é uma extensão do ReactElement que adiciona a especificidade do JSX. Basicamente, JSX.Element é um ReactElement<any, any>. Quando você escreve <div /> em JSX, o TypeScript vê exatamente JSX.Element.



const jsxElement: JSX.Element = <div>JSX.Element</div>;


A principal diferença do ReactElement é que JSX.Element não é parametrizado. É simplesmente "qualquer elemento JSX".



ReactNode

Este é o tipo mais amplo. ReactNode inclui:

  • ReactElement
  • Strings
  • Números
  • Booleans (true/false)
  • null e undefined
  • Arrays dos itens acima
  • React Portal


Em palavras simples: ReactNode é tudo que o React pode renderizar. Este é o tipo usado para children em componentes.



type ReactNode =   | React.ReactElement  | string  | number  | boolean  | null  | undefined  | React.ReactNode[];


Quando usar o quê? Cenários práticos



Agora a parte interessante — vamos analisar qual tipo escolher em situações reais.



Cenário 1: Valor de retorno do componente

Seu componente retorna JSX. Qual tipo especificar?



// ❌ Ruim: tipo muito genéricofunction MyComponent(): ReactNode {  return <div>Olá</div>;}

// ✅ Bom: usar JSX.Elementfunction MyComponent(): JSX.Element { return <div>Olá</div>;}

// ✅ Ótimo: se precisar de tipagem estrita das propsfunction MyComponent(): React.ReactElement<{ title: string }> { return <div>Olá</div>;}


Por quê? O componente sempre retorna JSX (ou null, se não renderizar nada). ReactNode é muito amplo — permite retornar string, número ou array, o que pode causar erros inesperados.



Cenário 2: children no componente

Aqui, ReactNode é seu melhor amigo. Elementos filhos podem ser qualquer coisa: string, outro componente, null (renderização condicional) ou array.



interface CardProps {  title: string;  children: React.ReactNode; // ✅ Correto}

function Card({ title, children }: CardProps): J

Blogs

Book Recommendations