根据prop改变react组件类型



我正在创建一个名为text的React组件,该组件允许更改将要呈现的标签。

export interface TextProps extends HTMLAttributes<HTMLElement> {
children: ReactNode;
as?: React.ElementType;
}

问题是,我试图使用这样的time元素:

<Text as="time" dateTime="2018-07-07">
July 7
</Text>

但是TS编译器抱怨Property 'dateTime' does not exist on type 'IntrinsicAttributes & TextProps'

我甚至尝试使用interface TextProps extends HTMLAttributes<HTMLTimeElement>,但我仍然得到相同的错误。

老实说,我不知道如何在这种组件上实现类型安全

如果你想让as支持任何内置的HTML元素,我们可以使用JSX.IntrinsicElements接口,它将HTML标签名称映射到它们的道具。

type IntrinsicProps = {
[K in keyof JSX.IntrinsicElements]: JSX.IntrinsicElements[K] & { as: K; }
}[keyof JSX.IntrinsicElements]

此映射类型IntrinsicProps提供了props和as的所有有效配对的联合。如果没有提供可选的as道具,我们需要添加更多的道具类型。这取决于你使用的默认标签。

type TextProps = IntrinsicProps | ( HTMLAttributes<HTMLElement> & { as?: never } )

你可以将children添加到道具中,也可以使用React.FC自动添加children

const Text: React.FC<TextProps> = (props) => {
/* ... */
}

现在你可以添加dateTime作为道具,但只有当你的as类型支持它!

如此:

<Text as="time" dateTime="2018-07-07">July 7</Text>

但是这会给出一个错误"Property'dateTime'does not exist on typeIntrinsicAttributes & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; } & { ...; }">

<Text as="div" dateTime="2018-07-07">July 7</Text>

Typescript Playground Link

试试React.TimeHTMLAttributestype

export interface TextProps extends React.TimeHTMLAttributes<HTMLElement> {
children: ReactNode;
as?: React.ElementType;
}

相关内容

  • 没有找到相关文章

最新更新