reactjs - Skicka generiska typer till funktionskomponent React Typescript
Jag undrade bara om det finns ett sätt att hantera detta med generics istället för att använda any för följande.
Jag försöker fortfarande förstå typer och generics, ville bara undvika att använda any. Eller skulle detta vara ett accepterat fall av att använda any!
SlotRenderer.tsx
// Can this be done ?
interface SlotAProps<T> {
slotData : T[]
}
// Should I stick with
interface SlotAProps {
slotData : any[]
}
const SlotRenderer = (props: SlotAProps) => {
return (
<div>
<p>Renders slot</p>
// for version 1 I could do, currently this throws an error
<p>{props.slotData[0]?.validity}</p>
// for version 2 I could do, currently this throws an error
<p>{props.slotData[0]?.totalPrice}</p>
</div>
)
}
De tillgängliga typerna är
interface SampleOne {
id: number;
name: string;
validity: string;
isVisible: boolean;
}
interface SampleTwo {
id: number;
required: true
sampleString: string;
totalPrice: number;
}
Verkställandet skulle vara
// Version 1
const Container = () => {
return (
<ComponentBase
// Passes a component to the Base component
slot={<SlotRenderer<SampleOne> slotData={[{ id: 1, name:'', validity:'', isVisible:'' }]} />}
/>
)
}
// Version 2
const ContainerTwo = () => {
return (
<ComponentBase
// Passes a component to the Base component
slot={<SlotRenderer<SampleTwo> slotData={[{ id: 1, required:true, sampleString:'', totalPrice:10 }]} />}
/>
)
}
Svar #1
Det enda du saknade var att lägga till en typvariabel till komponentfunktionen:
const SlotRenderer = <T extends unknown>(props: SlotAProps<T>) => {
// ...
}
Så anledningen till att du inte kunde göra det tidigare är att du korrekt definierade den generiska props-typen och känner till syntaxen för att använda generiska komponenter i tsx, men inte var medveten om att du skulle behöva denna extra typvariabel för att föra vidare den till den generiska props-typen.
The extends unknown i exemplet ovan är ett trick för att möjliggöra en typparameter i en pilfunktion i .tsx-filer, eftersom syntaxen annars är tvetydig med en komponents öppningstag.
Du kan hitta fler tips för att arbeta med TypeScript+React i React TypeScript Cheatsheet-projektet.
Svar #2
Problemet med den accepterade lösningen är att, åtminstone på min dator, när du använder SlotRenderer med en konkret typ, kommer TypeScript att behandla det som okänt.
Min metod är att använda en högre ordningens komponent, som:
const createSlotRenderer = <T,>({someParam: T}) => {
const SlotRenderer: React.FC<SlotAProps<T>> = props => {
doSomethingWith(someParam);
return <div>props.label</div>;
};
return SlotRenderer;
};
Du skulle använda det så här:
const SlotRenderer = createSlotRenderer(someParam);
return <SlotRenderer {...{props}} />
Fördelen är att i denna version kommer komponenten att använda den konkreta typen av someParam och till exempel om du har i dina props någon funktion som accepterar ett argument av typen T, kommer din komponent att kalla på den med den faktiska typen du använde istället för unknown.
