Eu tenho um componente funcional muito simples como segue:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
E outro 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;
Continuo recebendo o seguinte erro:
[ts] Tipo de elemento JSX 'ReactNode' não é uma função de construtor para elementos JSX. O tipo 'undefined' não pode ser atribuído ao tipo 'ElementClass'. [2605]
Como faço para digitar isso corretamente?
reactjs
typescript
jsx
typescript2.0
Asool
fonte
fonte
JSX.Element
não é bom o suficiente, pois um filho React válido pode ser uma string, um booleano, nulo ... tambémReactChild
está incompleto pelos mesmos motivosReactNode
. Não ajuda em termos de segurança de tipo, semelhante a digitarchildren
comoany
- veja minha resposta para uma explicação.Para usar
<Aux>
em seu JSX, ele precisa ser uma função que retornaReactElement<any> | null
. Essa é a definição de um componente de função .No entanto, atualmente é definido como uma função que retorna
React.ReactNode
, que é um tipo muito mais amplo. As tipificações React dizem:Certifique-se de que os tipos indesejados sejam neutralizados envolvendo o valor retornado em React Fragment (
<></>
):fonte
children
em um fragmento de reação. Importa-se de explicar? No React é perfeitamente válido apenasreturn children;
.children
for uma matriz. Se for esse o caso, você precisa envolvê-los em um único nó ou usar React Fragments.return React.Children.count(children) > 1 ? <>{children}</> : children
:, mas o texto datilografado reclama disso. Eu substituí por apenas<>{children}</>
.children
é uma lista de elementos que contém apenas 1 item. Acho que funcionaria se você fizessereturn React.Children.count(children) > 1 ? <>{children}</> : children[0]
@sanfilippopablo<React.Fragment>
envolvente{props.children}
não estou devolvendo nada.Isto é o que funcionou para mim:
Editar Eu recomendaria usar
children: React.ReactNode
agora.fonte
<MyComponent>{ condition ? <span>test</span> : null}</MyComponent>
. Usarchildren: ReactNode
vai funcionar.você pode declarar seu componente assim:
fonte
Você pode usar
ReactChildren
eReactChild
:fonte
Do site TypeScript: https://github.com/Microsoft/TypeScript/issues/6471
Isso funcionou para mim. O nó filho pode ser muitas coisas diferentes, então a digitação explícita pode perder casos.
Há uma discussão mais longa sobre o problema de acompanhamento aqui: https://github.com/Microsoft/TypeScript/issues/13618 , mas qualquer abordagem ainda funciona.
fonte
O tipo de retorno do componente de função é limitado
JSXElement | null
em TypeScript. Esta é uma limitação de tipo atual, o React puro permite mais tipos de retorno.Trecho mínimo de demonstração
Você pode usar uma declaração de tipo ou fragmentos como solução alternativa:
ReactNode
children: React.ReactNode
pode ser inferior ao ideal, se o objetivo for ter tipos fortes paraAux
.Quase tudo pode ser atribuído ao
ReactNode
tipo atual , que é equivalente a{} | undefined | null
. Um tipo mais seguro para o seu caso poderia ser:Exemplo:
Dadas
Aux
necessidades React elementos comochildren
, acidentalmente adicionamos astring
a ele. Então, a solução acima seria um erro em contraste comReactNode
- dê uma olhada nos playgrounds vinculados.Digitados
children
também são úteis para adereços não JSX, como um retorno de chamada Render Prop .fonte
Você também pode usar
React.PropsWithChildren<P>
.fonte
A maneira geral de encontrar qualquer tipo é por exemplo. A beleza do texto datilografado é que você tem acesso a todos os tipos, desde que tenha os
@types/
arquivos corretos .Para responder a isso eu mesmo pensei em um componente reage usa que tem o
children
prop. A primeira coisa que me veio à cabeça? Que tal um<div />
?Tudo que você precisa fazer é abrir o vscode e criar um novo
.tsx
arquivo em um projeto react com@types/react
.Passar o mouse sobre o
children
adereço mostra o tipo. E o que você sabe - Seu tipo éReactNode
(não há necessidade deReactNode[]
).Então, se você clicar na definição de tipo, será direcionado diretamente para a definição de
children
vir daDOMAttributes
interface.fonte
Como um tipo que contém filhos, estou usando:
Este tipo de contêiner filho é genérico o suficiente para suportar todos os casos diferentes e também está alinhado com a API ReactJS.
Então, para o seu exemplo, seria algo como:
fonte
Essas respostas parecem estar desatualizadas - o React agora tem um tipo integrado
PropsWithChildren<{}>
. É definido de forma semelhante a algumas das respostas corretas nesta página:type PropsWithChildren<P> = P & { children?: ReactNode };
fonte
P
o caso desse tipo?P
é o tipo de adereços do seu componenteOs componentes React devem ter um único nó wrapper ou retornar uma matriz de nós.
Seu
<Aux>...</Aux>
componente possui dois nósdiv
emain
.Tente envolver seus filhos em um
div
noAux
componente.fonte