reactjs - Finns det ett sätt att extrahera typen av props för ett JSX-element?
Min avsikt är att extrahera props från ett givet JSX-element, är det möjligt?
Detta var i princip mitt misslyckade försök... Tack på förhand för all hjälp ;)
function getComponentProps<T extends React.ReactElement>(element: T): ExtractProps<T>;
function Component({ name }: { name: string }) {
return <h1>{name}</h1>;
}
type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends React.ComponentType<infer TProps>
? TProps
: TComponentOrTProps;
const componentProps = getComponentProps(<Component name="jon" />); //type is JSX.Element
Svar #1
För det mesta kan du inte göra detta.
I teori är React.ReactElement-typen generisk med en typparameter P som beror på props. Så om du skulle ha ett starkt typat element skulle du kunna arbeta baklänges.
type ElementProps<T extends React.ReactNode> = T extends React.ReactElement<infer P> ? P : never;
I verkligheten får du endast en korrekt props-typ om du skapar ditt element genom React.createElement istället för JSX.
Alla JSX-element <Component name="John" /> får bara typen JSX.Element vilket uppenbarligen inte har någon information om props, så du kan inte arbeta bakåt från det till en props-typ.
const e1 = React.createElement(
Component,
{ name: 'John' }
)
type P1 = ElementProps<typeof e1> // type: {name: string}
console.log(getElementProps(e1)); // will log {name: "John"}
const e2 = <Component name="John" />
type P2 = ElementProps<typeof e2> // type: any
console.log(getElementProps(e2)); // will log {name: "John"}
Lekplatslänk
Det är mycket lättare att närma sig situationen från en annan vinkel. Du kommer att kunna härleda rätt props-typ om din funktion tar en komponent som Component eller div snarare än ett löst element. Du kan använda hjälpverktygstypen ComponentProps för funktions- och klasskomponenter och kartan JSX.IntrinsicElements för inbyggda.
Svar #2
Du kan extrahera typen av Props för vilken komponent som helst med
React.ComponentProps<typeof T>
Du kan hänvisa till detta TS Playground för fler alternativ
import * as React from 'react';
type TProps = {
name:string;
age:number;
isStackoverflow:boolean;
}
const App = (props:TProps) => <div>Hello World</div>;
//You can extract any components props like this.
type AppProps = React.ComponentProps<typeof App>;
`
