How can I declare a PropType corresponding to a nullable number?

JavascriptReactjsReact Native

Javascript Problem Overview


I'm looking for a PropType that means

> "this is required, and it will either be a number or be null"

In other words, what I have now is

PropTypes.number.isRequired

but that throws a warning if a null value gets passed in, yet I want null to be an acceptable value.

Javascript Solutions


Solution 1 - Javascript

Just use:

PropTypes.number

By default all prop types aren't required (i.e. allow null or undefined) unless you pop a .isRequired on the end of them.

You can see the full docs for proptypes here:

Solution 2 - Javascript

You simply could use: >PropTypes.number

and in defaultProps: >yourPropName: null

Solution 3 - Javascript

Currently prop-types library don't allow this. The way i get around this is using a custom validation function

MyComponent.propTypes = {
  nullableArray: function(props, propName, componentName) {
    const { propName: data } = props;

    if (data === undefined) {
      return new Error(`Undefined ${propName} is not allowed`);
    }

    if (data !== null) {
      return; //this is allow when data is loading
    }

    if (!_.isArray(data)) {
      return new Error(`${propName} must be an array`);
    }
  }
};

You can make another step further to create a high order function to generate the validation function. this should get you started

generateRequiredOrNullValidationFunction = expectedType => {
  if (expectedType !== "array") {
    return Error(`Unexpected ${expectedType}`);
  }

  return function(props, propName, componentName) {
    const { [propName]: data } = props;

    if (data === undefined) {
      return new Error(`Undefined ${propName} is not allowed`);
    }

    if (data !== null) {
      return; //this is allow when data is loading
    }

    if (expectedType === "array" && !_.isArray(data)) {
      return new Error(`${propName} must be an array`);
    }
  };
};

In this snippet, expectedType is a enumeration such as bool , array, number ...

Solution 4 - Javascript

To help with this quite common issue, I created a clean and fully-typed wrapper called better-prop-types:

import BetterPropTypes from 'better-prop-types'

// ...

MyComponent.propTypes = {
  aProp: BetterPropTypes.string.isRequiredButNullable,
}

Solution 5 - Javascript

import propTypes from 'prop-types';

const nullable = propType => (props, propName, ...rest) =>
  props[propName] === null ? null : propType(props, propName, ...rest);

const testMe = {
  a: 'string',
  b: 420,
  c: null,
  d: undefined,
  e: undefined
};

const testSchema = {
  a: nullable(propTypes.string.isRequired),
  b: nullable(propTypes.string.isRequired),
  c: nullable(propTypes.number.isRequired),
  d: nullable(propTypes.bool.isRequired),
  e: nullable(propTypes.number)
};

propTypes.checkPropTypes(testSchema, testMe, 'prop', 'testMe');
// Warning: Failed prop type: Invalid prop `b` of type `number` supplied to `testMe`, expected `string`.
// Warning: Failed prop type: The prop `d` is marked as required in `testMe`, but its value is `undefined`.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMs. CorlibView Question on Stackoverflow
Solution 1 - JavascriptctrlplusbView Answer on Stackoverflow
Solution 2 - JavascriptEduard FedorukView Answer on Stackoverflow
Solution 3 - JavascriptLu TranView Answer on Stackoverflow
Solution 4 - JavascriptIvan GabrieleView Answer on Stackoverflow
Solution 5 - JavascriptAdamView Answer on Stackoverflow