public static function createFromParams($params, string $separator = '&'): self
    {
        if ($params instanceof self) {
            return new self(
                http_build_query($params->toParams(), '', $separator, PHP_QUERY_RFC3986),
                PHP_QUERY_RFC3986,
                $separator
            );
        }

        if ($params instanceof Traversable) {
            $params = iterator_to_array($params, true);
        }

        if (is_object($params)) {
            return new self(
                http_build_query($params, '', $separator, PHP_QUERY_RFC3986),
                PHP_QUERY_RFC3986,
                $separator
            );
        }

        if ([] === $params) {
            return new self(null, PHP_QUERY_RFC3986, $separator);
        }

        if (is_array($params)) {
            return new self(
                http_build_query($params, '', $separator, PHP_QUERY_RFC3986),
                PHP_QUERY_RFC3986,
                $separator
            );
        }

        throw new TypeError(sprintf('The parameter is expected to be iterable or an Object `%s` given', gettype($params)));
    }