public static function fromParts(array $domainParts, ?string $tld = null): HostnameInterface
    {
        if (count($domainParts) === 0) {
            throw new HostnameInvalidArgumentException('Domain parts [] is empty.');
        }

        if (!self::myValidateDomainParts($domainParts, $error)) {
            throw new HostnameInvalidArgumentException('Domain parts ["' . implode('", "', $domainParts) . '"] is invalid: ' . $error);
        }

        if (!self::myValidateTld($tld, $error)) {
            throw new HostnameInvalidArgumentException($error);
        }

        self::myNormalizeDomainParts($domainParts);
        self::myNormalizeTld($tld);

        return new self($domainParts, $tld);
    }