首页 > 解决方案 > 有没有办法提取 JSX 元素的道具类型?

问题描述

我的意图是从给定的 JSX 元素中提取道具,这可能吗?

这几乎是我失败的尝试......在此先感谢您的帮助;)

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

标签: reactjstypescriptjsxtypescript-typingstypescript-generics

解决方案


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

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

type ElementProps<T extends React.ReactNode> = T extends React.ReactElement<infer P> ? P : never;

实际上,只有通过而不是 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"}
const e2 = <Component name="John" />

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

console.log(getElementProps(e2)); // will log {name: "John"}

游乐场链接

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


推荐阅读