Art der generischen zustandslosen Komponentenreaktion? ODER Erweiterung der generischen Funktionsschnittstelle in Typoskript um eine weitere generische?
Lesezeit: 8 Minuten
Naman Kheterpal
Problem: Die Schnittstelle von Stateless Functional Component ist gegeben als
2: Verlängerung SFC Um eine neue Schnittstelle zu erstellen, wie in der folgenden Antwort erwähnt, würde der Prop-Typ der Komponente wie folgt aussehen any: Typescript React zustandslose Funktion mit generischen Parameter-/Rückgabetypen, die ich nicht möchte. Ich möchte den richtigen Typ für meine Requisite angeben
Was passiert, wenn Sie das Generikum ersetzen <T> mit <T extends {}> ?
– Jonas Wilms
21. Juli 2018 um 20:57 Uhr
gleicher Fehler. Da ich so etwas möchte:const myCom: <T>SFC<Prop<T>>
– Naman Kheterpal
21. Juli 2018 um 21:00 Uhr
Ich habe den Playground-Link in der Beschreibung @JonasW hinzugefügt.
– Naman Kheterpal
21. Juli 2018 um 21:03 Uhr
@NamanKheterpal Ich bin auf dasselbe Problem gestoßen und habe ein bisschen Zeit dafür gesucht. Hier finden Sie meine Lösung, wie Sie einen React SFC deklarieren und verwenden
könnte als Pfeilfunktionsausdruck mit einem Typparameter oder einer Typzusicherung analysiert werden, die auf eine Pfeilfunktion ohne Typparameter angewendet wird.
Ihre Deklaration stimmt nicht mit dem in der TypeScript-Spezifikation definierten Muster überein, daher funktioniert sie nicht.
Sie können die SFC-Schnittstelle jedoch nicht verwenden und sie einfach selbst deklarieren.
interface Prop<V> {
num: V;
}
// normal function
function Abc<T extends string | number>(props: Prop<T>): React.ReactElement<Prop<T>> {
return <div />;
}
// const lambda function
const Abc: <T extends string | number>(p: Prop<T>) => React.ReactElement<Prop<T>> = (props) => {
return <div />
};
export default function App() {
return (
<React.Fragment>
<Abc<number> num={1} />
<Abc<string> num="abc" />
<Abc<string> num={1} /> // string expected but was number
</React.Fragment>
);
}
Kann dieses Muster irgendwie verwendet werden, wenn Sie einen Schnittpunkttyp mit haben React.FC? Zum Beispiel würde ich meine Komponente in der Lage sein, Typargumente zu akzeptieren, aber auch zusammengesetzte Komponenten zu haben. Derzeit habe ich eine const Lambda fn-Komponente const Table = React.FC<TableProps> & { Row: React.ComponentType<RowProps> } Und ich möchte in der Lage sein, einen Typparameter zu verwenden, wenn ich diese Komponente verwende.
– Kizivat
28. Mai 2020 um 20:48 Uhr
Es gibt ein Muster, um dieses Problem zu mindern, indem ein generischer Komponententyp-Alias außerhalb der Komponente deklariert und dann einfach behauptet wird, wenn Sie ihn brauchen.
Nicht so hübsch, aber immer noch wiederverwendbar und streng.
interface IMyComponentProps<T> {
name: string
type: T
}
// instead of inline with component assignment
type MyComponentI<T = any> = React.FC<IMyComponentProps<T>>
const MyComponent: MyComponentI = props => <p {...props}>Hello</p>
const TypedComponent = MyComponent as MyComponentI<number>
Dies dient wahrscheinlich nicht dem Zweck von Generika. Der Entwickler muss möglicherweise die Funktionalität jeder Komponente neu schreiben und kann kein gemeinsames Verhalten haben. const MyComponent: MyComponentI = props => <p {...props}>Hello</p> Diese Zeile würde für jede Komponente wiederholt werden.
Ist <T extends any> verwendet, um zu vermeiden, dass TS es als Typzusicherung behandelt? Kluge Idee.
– Bruce Sonne
9. Februar 2020 um 3:17 Uhr
das ist richtig. Es kann hier auch einen anderen Typ erweitern, wenn dies erforderlich ist
– Chris
3. August 2021 um 21:40 Uhr
Ich verstehe es nicht … was würde es hier bedeuten, “es als Typbehauptung zu behandeln”? Würden Sie es bitte ein wenig erklären oder ein Beispiel dafür geben, was ohne das passiert extends any? Ich google darüber, finde aber nicht die richtige Richtung. Vielen Dank! @BruceSun & @chris
– Rocío García Luque
23. Mai um 7:03 Uhr
@RocíoGarcíaLuque Entschuldigung, ich habe mich geirrt, um zu vermeiden, dass der TS-Compiler es als JSX behandelt, aber nicht als “Type Assertion”. Kasse diese Codesandbox und seine Readme-Datei, um dies in einem echten Beispiel zu sehen.
– Bruce Sonne
30. Mai um 2:36 Uhr
@BruceSun ahhhh so eine dumme Sache: D Vielen Dank für die Codesandbox, ich hatte Mühe, dieses Codebit zu verstehen … Prost
– Rocío García Luque
30. Mai um 7:50 Uhr
Ich schlage eine ähnliche, wenn auch etwas andere Lösung vor (Brainstorming mit einem Freund). Wir haben versucht, einen Formik-Wrapper zu erstellen, und haben es auf folgende Weise geschafft, ihn zum Laufen zu bringen:
import React, { memo } from 'react';
export type FormDefaultProps<T> = {
initialValues: T;
onSubmit<T>(values: T, actions: FormikActions<T>): void;
validationSchema?: object;
};
// We extract React.PropsWithChildren from React.FunctionComponent or React.FC
function component<T>(props: React.PropsWithChildren<FormDefaultProps<T>>) {
// Do whatever you want with the props.
return(<div>{props.children}</div>
}
// the casting here is key. You can use as typeof component to
// create the typing automatically with the generic included..
export const FormDefault = memo(component) as typeof component;
Und dann verwenden Sie es wie folgt:
<FormDefault<PlanningCreateValues>
onSubmit={handleSubmit}
initialValues={PlanningCreateDefaultValues}
>
{/*Or any other child content in here */}
{pages[page]}
</FormDefault>
Ich konnte dies nicht mit Methodenausdrücken erreichen:
Ich habe einen Weg zu tun, aber ich bin mir nicht sicher, ob es perfekt ist oder nicht
interface ComponentProps<T> {
text: T;
}
export const Component= <T,>(props: ComponentProps<T>) => {
const { text } = props
const [s] = useState(0) // you can use hook
return (<div>yes</div>)
}
Sie können Komponenten wie folgt verwenden:
(
<>
<Component<string> text="some text" />
</>
)
Tuukka Haapasalo
Wenn Sie den FunctionComponent-Typ von React in die Typdefinition aufnehmen möchten (um beispielsweise den Rückgabetyp automatisch typgeprüft zu bekommen), können Sie ein Konstrukt wie dieses verwenden, wenn es Ihnen nichts ausmacht, die Typen ein wenig zu wiederholen:
interface MyProps<T> {
val: T
}
const Component: React.FC<MyProps<any>> = <T>({
val
}: MyProps<T>) => {
// Your code and hooks here
return <div>Heya</div>
}
Der Typ der Konstante Component ist React.FC<MyProps<any>>was bedeutet, dass Sie es mit jedem gültigen Wert für verwenden können MyProps Typparameter Taber da die Implementierung den generischen Typparameter neu angibt T innerhalb des Implementierungscodes ist sein Typ T und nicht anyund wird somit ordnungsgemäß typgeprüft. T könnte einschränkende Spezifizierer wie haben extends stringSie müssen sie nur sowohl in der Schnittstellenspezifikation als auch in der Signatur der Funktionsimplementierung wiederholen.
14037000cookie-checkArt der generischen zustandslosen Komponentenreaktion? ODER Erweiterung der generischen Funktionsschnittstelle in Typoskript um eine weitere generische?yes
Was passiert, wenn Sie das Generikum ersetzen
<T>
mit<T extends {}>
?– Jonas Wilms
21. Juli 2018 um 20:57 Uhr
gleicher Fehler. Da ich so etwas möchte:
const myCom: <T>SFC<Prop<T>>
– Naman Kheterpal
21. Juli 2018 um 21:00 Uhr
Ich habe den Playground-Link in der Beschreibung @JonasW hinzugefügt.
– Naman Kheterpal
21. Juli 2018 um 21:03 Uhr
@NamanKheterpal Ich bin auf dasselbe Problem gestoßen und habe ein bisschen Zeit dafür gesucht. Hier finden Sie meine Lösung, wie Sie einen React SFC deklarieren und verwenden
– ford04
4. November 2018 um 16:35 Uhr