Eu criei um <If />
componente de função simples usando o React:
import React, { ReactElement } from "react";
interface Props {
condition: boolean;
comment?: any;
}
export function If(props: React.PropsWithChildren<Props>): ReactElement | null {
if (props.condition) {
return <>{props.children}</>;
}
return null;
}
Permite escrever um código mais limpo, como:
render() {
...
<If condition={truthy}>
presnet if truthy
</If>
...
Na maioria dos casos, funciona bem, mas quando quero verificar, por exemplo, se uma determinada variável não está definida e depois passá-la como propriedade, ela se torna um problema. Vou dar um exemplo:
Digamos que eu tenho um componente chamado <Animal />
que possui os seguintes adereços:
interface AnimalProps {
animal: Animal;
}
e agora eu tenho outro componente que renderiza o seguinte DOM:
const animal: Animal | undefined = ...;
return (
<If condition={animal !== undefined} comment="if animal is defined, then present it">
<Animal animal={animal} /> // <-- Error! expected Animal, but got Animal | undefined
</If>
);
Como comentei, apesar de o fato de animal não estar definido, não tenho como dizer ao Typescript que já o verifiquei. A afirmação de animal!
funcionaria, mas não é isso que estou procurando.
Alguma ideia?
javascript
reactjs
typescript
Eliya Cohen
fonte
fonte
{animal !== undefined && <Anibal animal={animal} />}
funcionaria<Animal animal={animal as Animal} />
Respostas:
Parece impossível.
Motivo: se
If
alterarmos o conteúdo do componente depara o oposto
Você descobrirá que desta vez deseja que o diff de tipo seja processado da maneira oposta.
O que significa que não é independente, levando à conclusão de que não é possível diferenciar esse tipo nessa condição, sem tocar em nenhum dos dois componentes.
Não tenho certeza de qual é a melhor abordagem, mas aqui está um dos meus pensamentos.
Você pode definir
Animal component
os adereçosanimal
com ostipos condicionais distributivos do texto datilografado : NonNullable .
Documento
Uso
Ele não é gerado pela
If
condição do componente, mas como você usa apenas ochild component
interior dessa condição, faz algum sentido projetar oschild component
adereços comonone nullable
, sob a condição quefonte
Resposta curta?
Você não pode.
Como você definiu
animal
comoAnimal | undefined
, a única maneira de removerundefined
é criar uma proteção ou reformularanimal
como outra coisa. Você ocultou a proteção de tipo em sua propriedade de condição, e o TypeScript não tem como saber o que está acontecendo lá; portanto, não pode saber se você está escolhendo entreAnimal
eundefined
. Você precisará transmiti-lo ou usá-lo!
.Considere, no entanto: isso pode parecer mais limpo, mas cria um código que precisa ser entendido e mantido, talvez por outra pessoa mais adiante. Em essência, você está criando uma nova linguagem, composta de componentes React, que alguém precisará aprender além do TypeScript.
Um método alternativo para gerar JSX condicionalmente é definir variáveis
render
que contenham seu conteúdo condicional, comoEssa é uma abordagem padrão que outros desenvolvedores reconhecerão instantaneamente e não precisarão procurar.
fonte
Usando um retorno de chamada de renderização, sou capaz de digitar que o parâmetro de retorno não é nulo.
Não consigo modificar o seu
If
componente original , pois não sei o que o seucondition
afirma e também que variável ele afirmoucondition={animal !== undefined || true}
Infelizmente, criei um novo componente
IsDefined
para lidar com este caso:Indicando que
children
será um retorno de chamada, que receberá um NonNullable do tipo T, que é do mesmo tipo quecheck
.Com isso, obteremos um retorno de chamada de renderização, que receberá uma variável verificada com nulo.
Eu tenho um exemplo de trabalho aqui https://codesandbox.io/s/blazing-pine-2t4sm
fonte
If
componente (para que possa parecer limpo).