# Type Checking

[PropTypes](https://www.npmjs.com/package/prop-types) is a library for React that verifies at runtime if props have the correct type, and if required props are passed.&#x20;

{% hint style="warning" %}
PropTypes are only used in development builds, which means that production builds will be more efficient - but it also means that you should not rely on PropTypes being present in the production build!
{% endhint %}

PropTypes are declared as a static field:

{% code title="component/CategoryPaginationLink/CategoryPaginationLink.component.js (annotated excerpt)" %}

```javascript
import { ChildrenType } from 'Type/Common';

export class CategoryPaginationLink extends PureComponent {
    static propTypes = {
        // component children are treated as props in React
        // by leaving out .isRequired, we make them optional
        children: ChildrenType,
        // we expect the getPage prop to be a function
        // it is required, so this will emit a warning if
        // getPage is not provided
        getPage: PropTypes.func.isRequired,
        // isCurrent expects a boolean
        isCurrent: PropTypes.bool.isRequired,
        // expects a string
        url_path: PropTypes.string.isRequired,
        // expects a number
        pageNumber: PropTypes.number.isRequired
    };
    
    static defaultProps = {
        // we must provide a default value for every prop that
        // is optionalex
        children: []
    };
```

{% endcode %}

## Advanced Types

Sometimes you want to specify that a prop expects something more complex than a number or a string. You can check the [official documentation](https://www.npmjs.com/package/prop-types#usage) to learn how to use:

* `instanceOf` to expect an instance of a class
* `oneOf` to expect an enum-like value that can have one of the specified values
* `oneOfType` to indicate that this prop may have one of the specified types
* `arrayOf` or `objectOf` to specify that this prop is an array or object where each value has the specified type
* `shape` or `exact` to specify that the prop should be an object, as well as what keys and values you expect it to have

For example, you could specify that a prop expecting a payment method should be given an object with two string properties:

```javascript
PropTypes.shape({
    code: PropTypes.string,
    title: PropTypes.string
});
```

However, it is likely that this "complex" type would be needed in multiple places in the application. Copy-pasting the same PropType definition would lead to code duplication, and a hard-to-maintain codebase. Instead, we prefer defining these types in the `type` directory and exporting them for re-use:

{% code title="type/Checkout.js (excerpt)" %}

```javascript
import PropTypes from 'prop-types';

export const paymentMethodType = PropTypes.shape({
    code: PropTypes.string,
    title: PropTypes.string
});
```

{% endcode %}

Now, we can use this type definition anywhere we want:

{% code title="component/CheckoutPayment/CheckoutPayment.component.js (excerpt)" %}

```javascript
import { paymentMethodType } from 'Type/Checkout';

/** @namespace Component/CheckoutPayment/Component */
export class CheckoutPayment extends PureComponent {
    static propTypes = {
        method: paymentMethodType.isRequired,
        onClick: PropTypes.func.isRequired,
        isSelected: PropTypes.bool
    };
```

{% endcode %}
