reactjs - 根据道具更改反应组件类型
问题描述
我正在创建一个名为 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 标记名称映射到它们的 props。
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>
但这会给出错误“'dateTime'
类型上不存在属性IntrinsicAttributes & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; } & { ...; }
”
<Text as="div" dateTime="2018-07-07">July 7</Text>
推荐阅读
- php - 无法在 wordpress 中将 js 文件排入队列
- python - 如何将 csv 文件加载到 pandas 中以在数据框中使用它
- database - 用于内部和外部使用的 postgresql 数据库设置
- r - 使用管道和 dplyr 将项目附加到列表
- android - 请求重试最佳实践
- python - 后 Django 测试过程中的错误
- html - 将多个静态文本覆盖添加到内联 SVG
- reactjs - (react-native-tab-view) 在 TabBar 中使用 navigation.navigate?
- scalardb - 如果执行重复的 Put,ScalarDB 是否会抛出 NoMutationApplied 异常
- pandas - 不再可以用日期索引 pandas DatetimeIndex?