[英]Require a specific type of functional component as a prop in React with Typescript
Say you have a component tree like:假设您有一个组件树,例如:
function Parent(props: { componentProp: ReactElement }) {
return (
<>
{props.componentProp}
</>
);
}
function ChildA(props: { message: string }) { return (<h1>{props.message}</h1>) }
function ChildB(props: { message: string }) { return (<h2>{props.message}</h2>) }
function App() {
return (
<Parent componentProp={<ChildA message="hi"/>}
);
}
As written, you could replace ChildA
with ChildB
in componentProp
and Typescript would not complain.如所写,您可以在
componentProp
中将ChildA
替换为 ChildB 并且ChildB
不会抱怨。
Is it possible to restrict the type of componentProp
such that you could only pass ChildA
, and passing ChildB
would throw a type error?是否可以限制
componentProp
的类型,使您只能传递ChildA
,而传递ChildB
会引发类型错误?
The type of any rendered JSX is always the same -- I don't know of any way to distinguish them.任何呈现的 JSX 的类型总是相同的——我不知道有什么方法可以区分它们。 Even if you do something like this, the rendered JSX type is unaffected by the function return type:
即使你这样做,呈现的 JSX 类型也不受 function 返回类型的影响:
type Valid = ReactElement & { __valid: true }
function ChildA(props: { message: string }): Valid {
const result = <h1>{props.message}</h1>
return { ...result, __valid: true } // fails
}
const ca = <ChildA message="foo"/> // still ReactElement
However, you can distinguish the component functions themselves, and pass them as props instead of their rendered versions.但是,您可以区分组件函数本身,并将它们作为道具而不是渲染版本传递。 If the valid components have different props, then you can ride off that, otherwise you could add either a junk prop or a junk return object property:
如果有效组件具有不同的道具,那么您可以摆脱它,否则您可以添加垃圾道具或垃圾返回 object 属性:
export default null
type Valid = (props: unknown) => ReactElement & { _valid: null }
// option 1:
const A = () => {
const result = <></>
return { ...result, _valid: null }
}
// option 2:
const B = (() => <></>) as unknown as Valid
const C = () => <></>
function Parent({ Child }: { Child: Valid }) {
return <><Child /></>
}
function App() {
return (
<>
<Parent Child={A} /> {/*passes*/}
<Parent Child={B} /> {/*passes*/}
<Parent Child={C} /> {/*fails*/}
</>
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.