search

Home  >  Q&A  >  body text

Can types in TypeScript be inferred from PropTypes?

<p>I know how to infer the type in this case: </p> <pre class="brush:php;toolbar:false;">import PropTypes from 'prop-types'; const props = { id: PropTypes.number, }; type Props = PropTypes.InferProps<typeof props>; const x: Props = {}; x.id; // number | null | undefined</pre> <p>However, in my case I have:</p> <pre class="brush:php;toolbar:false;">const propsShape = PropTypes.shape({ id: PropTypes.number, // More properties including nested PropTypes.shape calls });</pre> <p>If I try:</p> <pre class="brush:php;toolbar:false;">type PropsFromShape = PropTypes.InferProps<typeof propsShape>; const y: PropsFromShape = {}; const z = y.id;</pre> <p>It failed to compile: </p> <pre class="brush:php;toolbar:false;">Type '{}' is not assignable to type 'PropsFromShape'. Property 'isRequired' is missing in type '{}' but required in type 'InferPropsInner<Pick<Requireable<InferProps<{ id: Requireable<number>; }>>, "isRequired">>'. Property 'id' does not exist on type 'PropsFromShape'.</pre> <p>I could extract the parameter of <code>shape</code> into a separate constant and do it as above, but is there a way to directly infer the property type from <code>propsShape</code> A good way? </p>
P粉715304239P粉715304239469 days ago464

reply all(1)I'll reply

  • P粉872101673

    P粉8721016732023-08-15 09:53:53

    To get the type of a nested object, you can use type NestedProps = PropTypes.InferProps<typeof propsShape>['isRequired'];

    import PropTypes from "prop-types";
    
    const propsShape = PropTypes.shape({
      nestedId: PropTypes.number,
      // 更多包括嵌套的PropTypes.shape调用的属性
    });
    
    const props = {
      id: PropTypes.number,
      optionalWithShape: propsShape
    };
    
    type Props = PropTypes.InferProps<typeof props>;
    type NestedProps = PropTypes.InferProps<typeof propsShape>['isRequired'];
    
    const x: Props = {};
    x.id = 1;
    
    const y: NestedProps = {
      nestedId: 1
    }
    
    x.optionalWithShape = y;

    Alternatively, if you can put the entire props definition in one place:

    import PropTypes from "prop-types";
    
    const props = {
      id: PropTypes.number,
      optionalWithShape: PropTypes.shape({
        nestedId: PropTypes.number
      })
    };
    
    type Props = PropTypes.InferProps<typeof props>;
    type NestedProps = Props['optionalWithShape'];
    
    const x: Props = {};
    x.id = 1;
    
    const y: NestedProps = {
      nestedId: 1
    }
    
    x.optionalWithShape = y;
    
    console.log(x.optionalWithShape.nestedId);

    I personally think the latter is more readable.

    reply
    0
  • Cancelreply