def type_check(what, of_type, msg=None, allow_none=False):
    """Verify that object 'what' is of type 'of_type' and if not the case, raise a TypeError.

    :param what: the object to check
    :param of_type: the type (or tuple of types) to compare to
    :param msg: if specified, allows to customize the message that is passed within the TypeError exception
    :param allow_none: boolean, if True will not raise if the passed `what` is `None`

    :return: `what` or `None`
    """
    if allow_none and what is None:
        return None

    if not isinstance(what, of_type):
        if msg is None:
            msg = "Got object of type '{}', expecting '{}'".format(type(what), of_type)
        raise TypeError(msg)

    return what