spanishgum
spanishgum

Reputation: 1060

How do I check PropTypes for a functional component with a static method

I have a functional component that takes a component as a prop. That component always has a static method bound to it, but it is not limited to one type. How can I type check props?

const ElementA = () => { return <></> }
ElementA.staticCallable = (instance) => {}

const ElementB = () => { return <></> }
ElementB.staticCallable = (instance) => {}

const Component = ({ e }) => {
    const someVal = e.type.staticCallable(e)
    return <>{stuffWith(someVal)}</>
}

Component.propTypes = {
    e: PropTypes.shape({
        type: PropTypes.shape({
            staticCallable: PropTypes.func.isRequired
        }).isRequired,
    }).isRequired,
}

The problem here is that type is not an object, but a react element. So this works:

Component.propTypes = {
    e: PropTypes.shape({
        type: PropTypes.elementType.isRequired,
    }).isRequired,
}

However this is not checking that I have the static member. How can I do that?

For reference, this is how my parent looks:

const Parent = () => {
    const ea = <ElementA />
    const eb = <ElementB />

    return <>
        <Component e={ea} />
        <Component e={eb} />
    </>
}

Upvotes: 0

Views: 833

Answers (1)

spanishgum
spanishgum

Reputation: 1060

After reading through docs on github.com/facebook/prop-types, I found this:

// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
  if (!/matchme/.test(props[propName])) {
    return new Error(
      'Invalid prop `' + propName + '` supplied to' +
      ' `' + componentName + '`. Validation failed.'
    );
  }
},

I've never seen the /matchme/ syntax before, but I came up with something that works:

const elementShape = PropTypes.shape({
  type: (props, propName, componentName) => {
    PropTypes.checkPropTypes(
      {
        staticCallable: PropTypes.func,
      },
      props[propName],
      "static member",
      componentName
    )
  },
})

Component.propTypes = {
  e: elementShape.isRequired,
}

Changing getConnectPoint: PropTypes.func, to bool throws the warning:

Warning: Failed static member type: Invalid static member staticCallable of type function supplied to Component, expected boolean

While the "static member" string feels clunky in this scenario, the type checking is working.

Upvotes: 1

Related Questions