Hice un <If />componente de función simple usando 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;
}
Me permite escribir un código más limpio, como:
render() {
...
<If condition={truthy}>
presnet if truthy
</If>
...
En la mayoría de los casos, funciona bien, pero cuando quiero verificar, por ejemplo, si una variable dada no está definida y luego pasarla como propiedad, se convierte en un problema. Daré un ejemplo:
Digamos que tengo un componente llamado <Animal />que tiene los siguientes accesorios:
interface AnimalProps {
animal: Animal;
}
y ahora tengo otro componente que representa el siguiente 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 comenté, aunque de hecho animal no está definido, no tengo forma de decirle a Typecript que ya lo he comprobado. La afirmación de animal!funcionaría, pero eso no es lo que estoy buscando.
¿Algunas ideas?
javascript
reactjs
typescript
Eliya Cohen
fuente
fuente

{animal !== undefined && <Anibal animal={animal} />}funcionaría<Animal animal={animal as Animal} />Respuestas:
Parece imposible.
Motivo: si cambiamos
Ifel contenido del componente dea lo contrario
Descubrirá que esta vez desea que el tipo diff se procese de la manera opuesta.
Lo que significa que no es independiente, lo que lleva a la conclusión de que no es posible diferenciar ese tipo en esta condición, sin tocar ninguno de los dos componentes.
No estoy seguro de cuál es el mejor enfoque, pero este es uno de mis pensamientos.
Puede definir
Animal componentlos accesoriosanimalcon lostipos condicionales distributivos del mecanografiado : no anulables .
Documento
Uso
No se genera por la
Ifcondición del componente, pero dado que solo usa elchild componentinterior de esa condición, tiene sentido diseñar loschild componentaccesorios de la unidadnone nullable, bajo la condición de quefuente
¿Respuesta corta?
No puedes
Como lo has definido
animalcomoAnimal | undefined, la única forma de eliminarloundefinedes crear un guardia o refundirloanimalcomo otra cosa. Ha ocultado la protección de tipo en su propiedad de condición, y TypeScript no tiene forma de saber qué está sucediendo allí, por lo que no puede saber que está eligiendo entreAnimalyundefined. Tendrás que lanzarlo o usarlo!.Considere, sin embargo: esto puede sentirse más limpio, pero crea un fragmento de código que necesita ser entendido y mantenido, quizás por otra persona más adelante. En esencia, está creando un nuevo lenguaje, hecho de componentes React, que alguien necesitará aprender además de TypeScript.
Un método alternativo para generar JSX condicionalmente es definir variables
renderque contengan su contenido condicional, comoEste es un enfoque estándar que otros desarrolladores reconocerán instantáneamente y no tendrán que buscar.
fuente
Al usar una devolución de llamada de representación, puedo escribir que el parámetro de retorno no es anulable.
No puedo modificar su
Ifcomponente original , ya que no sé quéconditionafirma y qué variable afirmó.condition={animal !== undefined || true}Desafortunadamente, hice un nuevo componente
IsDefinedpara manejar este caso:Indicando que
childrenserá una devolución de llamada, que pasará un NonNullable de tipo T que es del mismo tipo quecheck.Con esto, obtendremos una devolución de llamada de renderizado, que pasará una variable de verificación nula.
Tengo un ejemplo de trabajo aquí https://codesandbox.io/s/blazing-pine-2t4sm
fuente
Ifcomponentes (para que pueda verse limpio)