在 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*/}
        </>
    )
}