web-dev-qa-db-fra.com

Comment restreindre le type d'enfants React Children dans TypeScript, en utilisant le nouveau support ajouté dans TypeScript 2.3?

J'essaie de profiter de récemment ajouté la prise en charge de la frappe des enfants dans le compilateur TypeScript et @ types/react, mais j'ai du mal. J'utilise la version 2.3.4 de TypeScript.

Disons que j'ai un code comme celui-ci:

interface TabbedViewProps {children?: Tab[]}
export class TabbedView extends React.Component<TabbedViewProps, undefined> {

  render(): JSX.Element {
    return <div>TabbedView</div>;
  }
}

interface TabProps {name: string}
export class Tab extends React.Component<TabProps, undefined> {
  render(): JSX.Element {
    return <div>Tab</div>
  }
}

Lorsque j'essaie d'utiliser ces composants comme ceci:

return <TabbedView>
  <Tab name="Creatures">
    <div>Creatures!</div>
  </Tab>
  <Tab name="Combat">
    <div>Combat!</div>
  </Tab>
</TabbedView>;

J'obtiens une erreur comme suit:

ERROR in ./src/TypeScript/PlayerView.tsx
(27,12): error TS2322: Type '{ children: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TabbedView> & Readonly<{ children?: ReactNode; }> ...'.
  Type '{ children: Element[]; }' is not assignable to type 'Readonly<TabbedViewProps>'.
    Types of property 'children' are incompatible.
      Type 'Element[]' is not assignable to type 'Tab[] | undefined'.
        Type 'Element[]' is not assignable to type 'Tab[]'.
          Type 'Element' is not assignable to type 'Tab'.
            Property 'render' is missing in type 'Element'.

Il semble inférer le type d'enfants comme simplement Element[] au lieu de Tab[] même si c'est le seul type d'enfants que j'utilise.

EDIT: Il serait également bien de restreindre l'interface des accessoires enfants au lieu de restreindre directement le type des composants enfants, car tout ce que je dois faire est de retirer des accessoires spécifiques des composants enfants.

29

Edit 2: Il s'avère que cette approche empêche l'avertissement, mais selon les commentaires TabProps ne sont pas correctement vérifiés.

Vous devriez essayer de définir les enfants de l'interface TabbedViewProps comme ceci

interface TabbedViewProps { children?: React.ReactElement<TabProps>[] }

L'idée ici n'est pas de dire à votre TabbedView qu'il a un tableau de Tab, mais de dire à votre TabbedView qu'il a un tableau de element qui prend des accessoires spécifiques . Dans votre cas TabProps.

Modifier (merci à Matei):

interface TabbedViewProps {
    children?: React.ReactElement<TabProps>[] | React.ReactElement<TabProps>
}
18
Pierre Ferry