在 React with Typescript 中需要特定类型的功能组件作为道具
Require a specific type of functional component as a prop in React with Typescript
假设你有一个像这样的组件树:
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"/>}
);
}
正如所写,您可以在 componentProp
中将 ChildA
替换为 ChildB
,Typescript 不会抱怨。
是否可以限制 componentProp
的类型,使您只能传递 ChildA
,而传递 ChildB
会引发类型错误?
任何呈现的 JSX 的类型总是相同的——我不知道有什么方法可以区分它们。即使你这样做,渲染的 JSX 类型也不受函数 return type:
的影响
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
但是,您可以区分组件功能本身,并将它们作为 props 传递,而不是它们的渲染版本。如果有效组件有不同的道具,那么你可以摆脱它,否则你可以添加垃圾道具或垃圾 return 对象 属性:
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*/}
</>
)
}
假设你有一个像这样的组件树:
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"/>}
);
}
正如所写,您可以在 componentProp
中将 ChildA
替换为 ChildB
,Typescript 不会抱怨。
是否可以限制 componentProp
的类型,使您只能传递 ChildA
,而传递 ChildB
会引发类型错误?
任何呈现的 JSX 的类型总是相同的——我不知道有什么方法可以区分它们。即使你这样做,渲染的 JSX 类型也不受函数 return type:
的影响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
但是,您可以区分组件功能本身,并将它们作为 props 传递,而不是它们的渲染版本。如果有效组件有不同的道具,那么你可以摆脱它,否则你可以添加垃圾道具或垃圾 return 对象 属性:
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*/}
</>
)
}