Type children dans React et TypeScript : guide complet

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Qu'est-ce qui se cache derrière la prop children dans React et TypeScript ?

\n\n

Si vous avez déjà écrit un composant React avec TypeScript, vous avez probablement été confronté à la question : "Quel est le type de données de la prop children ?". Cette question est l'une des plus populaires sur Stack Overflow, et pour cause. À première vue, la réponse semble simple : ReactNode. Mais le diable, comme on dit, se cache dans les détails.

\n\n

Dans cet article, nous ne donnerons pas simplement une réponse sèche. Nous analyserons tous les types possibles pour children, leurs différences, les bonnes pratiques et les pièges à éviter. Vous apprendrez quand utiliser ReactNode, quand utiliser ReactElement, et quand utiliser des types plus spécifiques. C'est parti !

\n\n

Pourquoi cette question est-elle si populaire ?

\n\n

Le problème est que children est une prop spéciale dans React. Elle peut être n'importe quoi :

\n\n
    \n
  • Une chaîne de caractères : "Bonjour, le monde !"
  • \n
  • Un nombre : {42}
  • \n
  • Un élément JSX : <div>...</div>
  • \n
  • Un tableau d'éléments : [<span/>, <span/>]
  • \n
  • Une fonction (render prop) : {() => <div/>}
  • \n
  • Même null, undefined ou boolean
  • \n
\n\n

En raison d'une telle flexibilité, les débutants écrivent souvent children: any, ce qui annule tous les avantages de TypeScript. Analysons les bonnes approches.

\n\n

Les principaux types pour children

\n\n

1. ReactNode — le soldat universel

\n\n

C'est le type le plus courant et le plus correct pour children dans 90% des cas. Il inclut tout ce que React peut afficher.

\n\n
import { ReactNode } from 'react';\n\ninterface CardProps {\n  title: string;\n  children: ReactNode;\n}\n\nfunction Card({ title, children }: CardProps) {\n  return (\n    <div className="card">\n      <h2>{title}</h2>\n      <div className="card-content">\n        {children}\n      </div>\n    </div>\n  );\n}\n\n// Utilisation :\n<Card title="Ma carte">\n  <p>Ce texte sera affiché</p>\n  {123} {/* Les nombres fonctionnent aussi */}\n  {null} {/* Et null */}\n</Card>
\n\n

Qu'est-ce qui est inclus dans ReactNode ? En fait, c'est une union de :

\n
    \n
  • ReactElement — les éléments JSX
  • \n
  • string et number — les primitives
  • \n
  • boolean, null, undefined — ignorés lors du rendu
  • \n
  • ReactNode[] — un tableau de ce qui précède
  • \n
  • ReactPortal — les portails
  • \n
\n\n

2. ReactElement — le mode strict

\n\n

Si vous avez besoin que children soit uniquement un élément JSX (pas une chaîne ni un nombre), utilisez ReactElement.

\n\n
import { ReactElement } from 'react';\n\ninterface StrictCardProps {\n  children: ReactElement; // Un seul élément JSX\n}\n\nfunction StrictCard({ children }: StrictCardProps) {\n  return <div className="strict-card">{children}</div>;\n}\n\n// Fonctionne :\n<StrictCard><span>Uniquement un élément</span></StrictCard>\n\n// Erreur TypeScript :\n<StrictCard>Texte</StrictCard> // ❌ La chaîne ne convient pas
\n\n

Important : ReactElement exige exactement un seul élément enfant. Si vous passez deux éléments sans les envelopper, TypeScript générera également une erreur.

\n\n

3. JSX.Element — un alias pour ReactElement

\n\n

Le type JSX.Element est simplement ReactElement<any, any>. Il est moins flexible que ReactNode et n'est généralement pas recommandé pour children, sauf si vous écrivez une bibliothèque.

\n\n
// En substance, c'est la même chose :\ntype A = JSX.Element;    // ReactElement<any, any>\ntype B = ReactElement;   // Re                

Blogs

Book Recommendations