【问题标题】:Require a specific type of functional component as a prop in React with Typescript [duplicate]在 React with Typescript 中需要特定类型的功能组件作为道具 [重复]
【发布时间】:2022-01-04 18:10:39
【问题描述】:

假设你有一个像这样的组件树:

 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 会引发类型错误?

【问题讨论】:

  • 乍一看,这看起来不像是同一个问题,但再看一遍是的,它确实表明您不能严格键入呈现的元素。

标签: reactjs typescript react-functional-component


【解决方案1】:

任何渲染的 JSX 的类型总是相同的——我不知道有什么方法可以区分它们。即使你这样做,渲染的 JSX 类型也不受函数返回类型的影响:

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,那么你可以忽略它,否则你可以添加一个垃圾 prop 或一个垃圾返回对象属性:

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

【讨论】:

  • 谢谢!很难证明为类型验证创建更糟糕的 API 是合理的。我想我一定是遗漏了一些明显的东西,但我想不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 2020-08-14
  • 2019-07-27
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
相关资源
最近更新 更多