private function parseInternal(): Type
    {
        $typeName = $this->match(Lexer::T_IDENTIFIER);
        if (! $this->lexer->isNextToken(Lexer::T_OPEN_BRACKET)) {
            return new Type($typeName);
        }

        $this->match(Lexer::T_OPEN_BRACKET);

        $params = [];
        do {
            if ($this->lexer->isNextToken(Lexer::T_IDENTIFIER)) {
                $params[] = $this->parseInternal();
            } elseif ($this->lexer->isNextToken(Lexer::T_STRING)) {
                $params[] = $this->match(Lexer::T_STRING);
            } else {
                $this->syntaxError();
            }
        } while (Lexer::T_COMMA === $this->lexer->lookahead['type'] && $this->lexer->moveNext());

        $this->match(Lexer::T_CLOSED_BRACKET);

        return new Type($typeName, $params);
    }