Búsqueda de sitios web

reactjs - Componentes Compuestos - React Typescript


Estoy intentando usar React TypeScript con Componentes Compuestos, pero estoy teniendo este error:

JSX element type 'Nav.Content' does not have any construct or call signatures.ts(2604)

Aquí hay un sandbox: https://codesandbox.io/s/compound-components-typescript-fjilh?file=/src/App.tsx

¿Alguna idea de cómo puedo solucionarlo?

Así es como se ve mi código:

Nav.tsx
interface ContentProps {
  children: ReactNode;
}
const Content: React.FC<ContentProps> = (props: ContentProps) => (
  <div>{props.children}</div>
);
interface ContentComposition {
  Content?: React.FC<ContentProps>;
}
interface Props {
  children: ReactNode;
}
const Nav: React.FC<Props> & ContentComposition = (props: Props) => (
  <div>{props.children}</div>
);

Nav.Content = Content;

export default Nav;

App.tsx
export default function App() {
  return (
    <div className="App">
      <Nav>
        <Nav.MainContent>
          <h2>Start editing to see some magic happen!</h2>
        </Nav.MainContent>
        <h1>Hello CodeSandbox</h1>
      </Nav>
    </div>
  );
}

Respuesta #1

Gracias a Brady de Reactiflux pude encontrar la respuesta.

El problema era que estaba usando React.FC

Más información sobre React.FC aquí: https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#function-components

Aquí está la respuesta:

interface ContentProps {
  children: ReactNode;
}
const Content = (props: ContentProps) => <div>{props.children}</div>;

interface Props {
  children: ReactNode;
}
const Nav = (props: Props) => <div>{props.children}</div>;

Nav.Content = Content;

export default Nav;

Respuesta #2

Una manera de abordar esto es la siguiente:

import React, { FC } from 'react';

interface SubComponentProps {
    /* ... */    
}
const SubComponent: FC<SubComponentProps> = () => {
    /* ... */
};

interface ParentComposition {
    Sub: typeof SubComponent; /* or you can do FC<SubComponentProps> */
}

interface ParentProps {
    /* ... */
}
const Parent: FC<ParentProps> & ParentComposition = () => {
    /* .... */
};

Parent.Sub = SubComponent;

export default Parent;

La clave aquí es usar la interfaz Composition y usarla al declarar el tipo de componente compuesto.

Artículos relacionados