Tengo un componente funcional muy simple de la siguiente manera:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
Y otro componente:
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
Sigo recibiendo el siguiente error:
[ts] El tipo de elemento JSX 'ReactNode' no es una función de constructor para elementos JSX. El tipo 'indefinido' no se puede asignar al tipo 'ElementClass'. [2605]
¿Cómo escribo esto correctamente?
reactjs
typescript
jsx
typescript2.0
Asool
fuente
fuente

JSX.Elementno es lo suficientemente bueno ya que un niño React válido podría ser una cadena, un booleano, nulo ... tambiénReactChildestá incompleto por las mismas razonesReactNode. No ayuda en términos de seguridad de tipos, similar a escribirchildrencomoany: vea mi respuesta para obtener una explicación.Para usarlo
<Aux>en su JSX, debe ser una función que regreseReactElement<any> | null. Esa es la definición de un componente de función. .Sin embargo, actualmente se define como una función que devuelve
React.ReactNode, que es un tipo mucho más amplio. Como dicen los mecanografiados de React:Asegúrese de que los tipos no deseados se neutralicen envolviendo el valor devuelto en React Fragment (
<></>):fuente
childrenen un fragmento de reacción. ¿Le importaria explicar? En React es perfectamente válido soloreturn children;.childrenson una matriz. Si ese es el caso, debe envolverlos en un solo nodo o usar React Fragments.return React.Children.count(children) > 1 ? <>{children}</> : childrenpero mecanografiado se queja de eso. Lo reemplacé con solo<>{children}</>.childrenes una lista de elementos que contiene solo 1 elemento. Creo que funcionaría si loreturn React.Children.count(children) > 1 ? <>{children}</> : children[0]hicieras @sanfilippopablo<React.Fragment>alrededores{props.children}no devuelvo nada.Esto es lo que funcionó para mí:
Editar , recomendaría usar en su
children: React.ReactNodelugar ahora.fuente
<MyComponent>{ condition ? <span>test</span> : null}</MyComponent>. El usochildren: ReactNodefuncionará.puedes declarar tu componente así:
fuente
Puede utilizar
ReactChildrenyReactChild:fuente
Desde el sitio de TypeScript: https://github.com/Microsoft/TypeScript/issues/6471
Eso funcionó para mí. El nodo hijo puede tener muchas cosas diferentes, por lo que la escritura explícita puede omitir casos.
Hay una discusión más larga sobre el problema de seguimiento aquí: https://github.com/Microsoft/TypeScript/issues/13618 , pero el enfoque any todavía funciona.
fuente
El tipo de retorno del componente de función está limitado a
JSXElement | nullTypeScript. Esta es una limitación de tipo actual, React puro permite más tipos de retorno.Fragmento de demostración mínimo
Puede usar una aserción de tipo o Fragmentos como solución alternativa:
ReactNodechildren: React.ReactNodepuede ser subóptimo, si el objetivo es tener tipos fuertes paraAux.Casi todo se puede asignar al
ReactNodetipo actual , que es equivalente a{} | undefined | null. Un tipo más seguro para su caso podría ser:Ejemplo:
Dadas las
Auxnecesidades de los elementos de React comochildren, accidentalmente le agregamos unstring. Entonces la solución anterior sería un error en contraste conReactNode: eche un vistazo a los patios de recreo vinculados.Typed
childrentambién es útil para accesorios que no son JSX, como una devolución de llamada de Render Prop .fuente
También puede utilizar
React.PropsWithChildren<P>.fuente
La forma general de encontrar cualquier tipo es mediante un ejemplo. La belleza del mecanografiado es que tiene acceso a todos los tipos, siempre que tenga los
@types/archivos correctos .Para responder a esto yo mismo, solo pensé en un componente que usa react que tiene el
childrenprop. ¿Lo primero que le vino a la mente? ¿Qué tal un<div />?Todo lo que necesita hacer es abrir vscode y crear un nuevo
.tsxarchivo en un proyecto de reacción con@types/react.Al pasar el cursor sobre el
childrenaccesorio, se muestra el tipo. ¿Y qué sabes? Su tipo esReactNode(no es necesarioReactNode[]).Luego, si hace clic en la definición de tipo, lo lleva directamente a la definición de interfaz
childrenprovenienteDOMAttributes.fuente
Como tipo que contiene niños, estoy usando:
Este tipo de contenedor para niños es lo suficientemente genérico para admitir todos los casos diferentes y también está alineado con la API de ReactJS.
Entonces, para su ejemplo, sería algo como:
fuente
Estas respuestas parecen estar desactualizadas: React ahora tiene un tipo integrado
PropsWithChildren<{}>. Se define de manera similar a algunas de las respuestas correctas en esta página:type PropsWithChildren<P> = P & { children?: ReactNode };fuente
Pen el caso de ese tipo?Pes el tipo de accesorios de su componenteLos componentes de React deben tener un solo nodo contenedor o devolver una matriz de nodos.
Su
<Aux>...</Aux>componente tiene dos nodosdivymain.Trate de envolver a sus hijos en una
divdeAuxcomponente.fuente