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
If
el 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 component
los accesoriosanimal
con lostipos condicionales distributivos del mecanografiado : no anulables .
Documento
Uso
No se genera por la
If
condición del componente, pero dado que solo usa elchild component
interior de esa condición, tiene sentido diseñar loschild component
accesorios de la unidadnone nullable
, bajo la condición de quefuente
¿Respuesta corta?
No puedes
Como lo has definido
animal
comoAnimal | undefined
, la única forma de eliminarloundefined
es crear un guardia o refundirloanimal
como 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 entreAnimal
yundefined
. 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
render
que 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
If
componente original , ya que no sé quécondition
afirma y qué variable afirmó.condition={animal !== undefined || true}
Desafortunadamente, hice un nuevo componente
IsDefined
para manejar este caso:Indicando que
children
será 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
If
componentes (para que pueda verse limpio)