英文:
Enforce Plain HTML Element Passed as Children in Typescript
问题
我正在尝试创建一个React组件,该组件强制其子元素为纯HTML元素(例如<p>...</p>
)而不是React组件(例如<SomeComponent/>
)。
这是我尝试过的一些代码,但没有成功
import React from "react";
interface ITooltipProps {
// 目标是要求这里有一个纯HTML子元素,即<p>...</p>,如果得到其他任何东西则出错
// children: React.ReactElement<JSX.IntrinsicElements[keyof JSX.IntrinsicElements]>;
// 这不起作用,因为JSX.IntrinsicElements映射只返回props,而不是元素类型
// children: JSX.IntrinsicElements[keyof JSX.IntrinsicElements];
// 这不起作用,因为它只是要求一个可以接受HTML元素的props的React组件(所有这些都是可选的)
children: React.ReactElement<JSX.IntrinsicElements[keyof JSX.IntrinsicElements]>;
}
export function Tooltip({
children
}: ITooltipProps) {
return (
<div>
{children}
</div>
)
}
// 一个元素,不返回纯HTML子元素
const F = () => {
return (
<>
<p>Hello</p>
<p>World</p>
</>
)
}
const x = (
// 期望<F/>出错,因为F不返回纯HTML对象/返回片段
<Tooltip>
<F/>
</Tooltip>
)
想知道是否有人知道如何强制组件的子元素是“原始”HTML元素,而不是React组件 - 谢谢!
英文:
I'm trying to create a React component which enforces that its children are plain HTML elements (such as <p>...</p>
) and not React components (such as <SomeComponent/>
)
Here's some code I've tried, to no avail
import React from "react"
interface ITooltipProps {
// Goal is to require a plain HTML child here, i.e. <p>...</p>, and error if we get anything else
// children: React.ReactElement<JSX.IntrinsicElements[keyof JSX.IntrinsicElements]>;
// This doesn't work because the JSX.IntrinsicElements map just returns props, not the element type
// children: JSX.IntrinsicElements[keyof JSX.IntrinsicElements];
// This doesn't work because it's just asking for a react component that can take props of an HTML element (all of which are optional)
children: React.ReactElement<JSX.IntrinsicElements[keyof JSX.IntrinsicElements]>;
}
export function Tooltip({
children
}: ITooltipProps) {
return (
<div>
{children}
</div>
)
}
// An element which doesn't return a plain HTML child
const F = () => {
return (
<>
<p>Hello</p>
<p>World</p>
</>
)
}
const x = (
// Expect <F/> to error, since F isn't returning a plain HTML object / is returning a fragment
<Tooltip>
<F/>
</Tooltip>
)
(Here's a link to a TS playground with the above code)
Am wondering if anybody knows how to enforce that a component's children are "primitive" HTML elements, as opposed to react components – thanks!
答案1
得分: 1
这不可能。
渲染的 JSX 具有 JSX.Element
的返回类型,无论它包含什么。因此,普通的 HTML、片段或渲染的组件都具有相同的类型。这意味着你不能用类型以这种方式来约束它。
英文:
This is not possible.
Rendered JSX has a return type of JSX.Element
no matter what it contains. So plain html, a fragment, or a rendered component all have the same type. Which means you can't use types to constrain it in this way.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论