public static function typeOf($types, ...$values): bool
    {
        if (is_string($types)) {
            $types = [$types];
        }

        if (is_array($types) === false) {
            throw new InvalidArgumentException(sprintf(static::MSG_TYPE_MISMATCH, gettype($types)));
        }

        foreach ($values as $value) {
            $isObject  = is_object($value);
            $match     = false;
            $valueType = gettype($value);

            // Check if current value is one of the specified types or instances
            foreach ($types as $type) {
                if (($isObject && $value instanceof $type) xor ($isObject === false && $valueType === $type)) {
                    $match = true;
                    break;
                }
            }

            // Throw type error
            if ($match === false) {
                if ($isObject) {
                    $message   = 'Expected value to be an instance of %s, instance of %s given!';
                    $valueType = get_class($value);
                } else {
                    $message = 'Expected value to be of type %s, %s given!';
                }

                throw new TypeError(sprintf($message, implode(' or ', $types), $valueType));
            }
        }

        return true;
    }