【问题标题】:How do I enforce passthrough props in TypeScript (in React) when passing a component as prop as well?在将组件作为道具传递时,如何在 TypeScript(在 React 中)强制传递道具?
【发布时间】:2020-10-19 03:56:24
【问题描述】:

假设我有 3 个组件(CompACompBCompC),CompC 调用 CompB 组件,后者调用 CompA 组件:

type PropsCompA = { param1: string };
const CompA = (props: PropsCompA) => (
  <p>{props.param1}</p>
)
type PropsCompA2 = { param2: string };
const CompA2 = (props: PropsCompA2) => (
  <p>{props.param2}</p>
)

type PropsCompB = {
  comp: React.StatelessComponent<any>;
  subProps: Record<string, any>;
};
const CompB = (props: PropsCompB) => (
  <props.comp { ...props.subProps }/>
)

const CompC = () => (
  <>
    <CompB subProps={{ param1: 'hello' }} comp={CompA} />
    <CompB subProps={{ param2: 'hello' }} comp={CompA2} />
  </>
)

有没有办法确保在调用CompB 时,传递给该组件的subProbscomp 属性的预期属性一致。即,现在CompA 期望道具为{param1: string},而CompA2 期望道具为{param2: string}。但是,将代码更改为此:

const CompC = () => (
  <>
    <CompB subProps={{ param33: 'hello' }} comp={CompA} />
    <CompB subProps={{ param44: 'hello' }} comp={CompA2} />
  </>
)

TypeScript 不会抛出错误。有没有办法让它这样 TypeScript 会抛出错误?我认为这与这一行有关:

type PropsCompB = {
  comp: React.StatelessComponent<any>;
  subProps: Record<string, any>;
};

但我不太确定。我对泛型相当熟悉,并且一直在使用泛型来解决这个问题,但仍然无法让它发挥作用。

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    您可以在传入的子组件props中制作CompBPropsCompBgeneric

    type PropsCompB<T> = {
        comp: React.StatelessComponent<T>;
        subProps: T;
    };
    
    const CompB = <T,>(props: PropsCompB<T>) => <props.comp {...props.subProps} />
    
    const CompC = () => (
        <>
            <CompB subProps={{ param1: 'hello' }} comp={CompA} /> // ✅
            <CompB subProps={{ param2: 'hello' }} comp={CompA2} /> // ✅
            <CompB subProps={{ param33: 'hello' }} comp={CompA} /> // ❌
            <CompB subProps={{ param44: 'hello' }} comp={CompA2} /> // ❌ 
        </>
    )
    

    Playground sample

    【讨论】:

      【解决方案2】:

      因此,Record 将在您的示例中将任何字符串值作为键。 Source。要更改这一点,您可以键入密钥,而不是允许它是任何字符串。

      你可以这样做:

      type ParamKeys = "param1" | "param2";
      type PropsCompB = {
        comp: React.StatelessComponent<any>;
        subProps: Record<ParamKeys, any>;
      };
      

      【讨论】:

        猜你喜欢
        • 2020-08-20
        • 2018-08-01
        • 2018-08-22
        • 2021-04-01
        • 2023-03-12
        • 1970-01-01
        • 2017-09-06
        • 2021-06-23
        • 2020-01-25
        相关资源
        最近更新 更多