有没有办法提取 JSX 元素的 props 类型?

Ped*_*edo 2 jsx typescript reactjs typescript-generics typescript-typings

我的目的是从给定的 JSX 元素中提取 props,这可能吗?

这几乎是我失败的尝试......提前感谢您的帮助;)

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
Run Code Online (Sandbox Code Playgroud)

Lin*_*ste 5

在大多数情况下,你不能这样做。

理论上,该类型是泛型的React.ReactElement其类型参数P取决于 props。因此,如果您有一个强类型元素,那么您可以向后工作。

type ElementProps<T extends React.ReactNode> = T extends React.ReactElement<infer P> ? P : never;
Run Code Online (Sandbox Code Playgroud)

实际上,只有通过而不是 JSX创建元素,您才会获得正确的 props 类型React.createElement

任何 JSX 元素<Component name="John" />都只是获取类型,JSX.Element而该类型显然没有有关 props 的信息,因此您无法从该类型反向工作到 props 类型。

const e1 = React.createElement(
  Component,
  { name: 'John' }
)

type P1 = ElementProps<typeof e1> // type: {name: string}

console.log(getElementProps(e1)); // will log {name: "John"}
Run Code Online (Sandbox Code Playgroud)
const e2 = <Component name="John" />

type P2 = ElementProps<typeof e2>  // type: any

console.log(getElementProps(e2)); // will log {name: "John"}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

从不同的角度来处理这个情况要容易得多。Component如果您的函数采用类似或 的组件div而不是已解析的元素,您将能够派生正确的 props 类型。您可以将ComponentProps实用程序类型用于函数和类组件,JSX.IntrinsicElements将映射用于内置组件。