Ich habe <If />
mit React eine einfache Funktionskomponente erstellt:
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;
}
Damit kann ich einen saubereren Code schreiben, wie zum Beispiel:
render() {
...
<If condition={truthy}>
presnet if truthy
</If>
...
In den meisten Fällen funktioniert es gut. Wenn ich jedoch beispielsweise überprüfen möchte, ob eine bestimmte Variable nicht definiert ist, und sie dann als Eigenschaft übergeben möchte, wird dies zu einem Problem. Ich werde ein Beispiel geben:
Angenommen, ich habe eine Komponente <Animal />
mit den folgenden Requisiten:
interface AnimalProps {
animal: Animal;
}
und jetzt habe ich eine andere Komponente, die das folgende DOM rendert:
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>
);
Wie ich kommentierte, obwohl Tier tatsächlich nicht definiert ist, kann ich Typescript nicht sagen, dass ich es bereits überprüft habe. Die Behauptung von animal!
würde funktionieren, aber das ist nicht das, wonach ich suche.
Irgendwelche Ideen?
quelle
{animal !== undefined && <Anibal animal={animal} />}
würde es funktionieren<Animal animal={animal as Animal} />
Antworten:
Es scheint unmöglich.
Grund: Wenn wir
If
den Inhalt der Komponente von änderndazu ist es entgegengesetzt
Sie werden feststellen, dass diesmal der Typ diff umgekehrt verarbeitet werden soll.
Dies bedeutet, dass es nicht unabhängig ist, was zu der Schlussfolgerung führt, dass es nicht möglich ist, einen solchen Typ in diesem Zustand zu unterscheiden, ohne eine der beiden Komponenten zu berühren.
Ich bin mir nicht sicher, was der beste Ansatz ist, aber hier ist einer meiner Gedanken.
Sie können die
Animal component
Requisitenanimal
mit denverteilenden bedingten Typen des Typoskripts definieren : NonNullable .
Dokumentieren
Verwendungszweck
Es wird nicht durch die
If
Bedingung der Komponente generiert , aber da Sie nur daschild component
Innere dieser Bedingung verwenden, ist es sinnvoll, diechild component
Requisiten der Komponente alsnone nullable
, unter der Bedingung zu entwerfen , dassquelle
Kurze Antwort?
Das kannst du nicht.
Da Sie
animal
als definiert habenAnimal | undefined
, besteht die einzige Möglichkeit zum Entfernenundefined
darin, entweder einen Schutz zu erstellen oderanimal
als etwas anderes neu zu fassen . Sie haben den Typschutz in Ihrer Bedingungseigenschaft ausgeblendet, und TypeScript kann nicht wissen, was dort passiert. Daher kann es nicht wissen, dass Sie zwischenAnimal
und wählenundefined
. Sie müssen es wirken oder verwenden!
.Bedenken Sie jedoch: Dies mag sich sauberer anfühlen, schafft jedoch einen Code, der verstanden und gepflegt werden muss, möglicherweise von einer anderen Person auf der ganzen Linie. Im Wesentlichen erstellen Sie eine neue Sprache aus React-Komponenten, die zusätzlich zu TypeScript von jemandem gelernt werden muss.
Eine alternative Methode zur bedingten Ausgabe von JSX besteht darin, Variablen zu definieren
render
, die Ihren bedingten Inhalt enthalten, zDies ist ein Standardansatz, den andere Entwickler sofort erkennen und nicht nachschlagen müssen.
quelle
Durch Verwendung eines Render-Rückrufs kann ich eingeben, dass der return-Parameter nicht nullwertfähig ist.
Ich kann Ihre ursprüngliche
If
Komponente nicht ändern, da ich nicht weiß, was Siecondition
behaupten und welche Variable sie behauptet, dhcondition={animal !== undefined || true}
Daher habe ich leider eine neue Komponente erstellt
IsDefined
, um diesen Fall zu behandeln:Dies zeigt an, dass
children
es sich um einen Rückruf handelt, an den ein NonNullable vom Typ T übergeben wird, der vom selben Typ ist wiecheck
.Damit erhalten wir einen Render-Rückruf, dem eine null-überprüfte Variable übergeben wird.
Ich habe hier ein Arbeitsbeispiel https://codesandbox.io/s/blazing-pine-2t4sm
quelle
If
Komponenten