Repository: microsoft/TypeScript
File: src/services/symbolDisplay.ts (TypeScript)

Code before:
                displayParts.push(textOrKeywordPart(symbolKind));
                displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
                return;
        }
    }

    function addSignatureDisplayParts(signature: Signature, allSignatures: readonly Signature[], flags = TypeFormatFlags.None) {
        addRange(displayParts, signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | TypeFormatFlags.WriteTypeArgumentsOfSignature));
        if (allSignatures.length > 1) {
            displayParts.push(spacePart());
            displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
            displayParts.push(operatorPart(SyntaxKind.PlusToken));
            displayParts.push(displayPart((allSignatures.length - 1).toString(), SymbolDisplayPartKind.numericLiteral));
            displayParts.push(spacePart());
            displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads"));
            displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
        }
        documentation = signature.getDocumentationComment(typeChecker);
        tags = signature.getJsDocTags();

        if (allSignatures.length > 1 && documentation.length === 0 && tags.length === 0) {
            documentation = allSignatures[0].getDocumentationComment(typeChecker);
            tags = allSignatures[0].getJsDocTags().filter(tag => tag.name !== "deprecated"); // should only include @deprecated JSDoc tag on the first overload (#49368)
        }

        if (symbolFlags & SymbolFlags.Alias && documentation.length === 0 && tags.length === 0) {
            const aliasSymbol = typeChecker.getAliasedSymbol(symbol);
            const aliasDeclaration = firstOrUndefined(aliasSymbol.declarations);
            if (aliasSymbol !== symbol && aliasDeclaration) {
                documentationFromAlias = aliasSymbol.getContextualDocumentationComment(aliasDeclaration, typeChecker);
                tagsFromAlias = aliasSymbol.getJsDocTags(typeChecker);
            }
        }
    }

    function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined) {
        const typeParameterParts = mapToDisplayParts(writer => {
            const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration, symbolDisplayNodeBuilderFlags);
            getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
        });
        addRange(displayParts, typeParameterParts);
    }
}

function isLocalVariableOrFunction(symbol: Symbol) {
    if (symbol.parent) {
        return false; // This is exported symbol
    }

    return forEach(symbol.declarations, declaration => {
        // Function expressions are local

Review comment (suggestion):
I think it would be better to put this code inside the existing `if (symbolFlags & SymbolFlags.Alias)` block around line 536. It already sets documentationFromAlias/tagsFromAlias under other conditions, so it would be a good idea to make sure they all work together.

Code after:
                displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
                return;
        }
    }

    function addSignatureDisplayParts(signature: Signature, allSignatures: readonly Signature[], flags = TypeFormatFlags.None) {
        addRange(displayParts, signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | TypeFormatFlags.WriteTypeArgumentsOfSignature));
        if (allSignatures.length > 1) {
            displayParts.push(spacePart());
            displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
            displayParts.push(operatorPart(SyntaxKind.PlusToken));
            displayParts.push(displayPart((allSignatures.length - 1).toString(), SymbolDisplayPartKind.numericLiteral));
            displayParts.push(spacePart());
            displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads"));
            displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
        }
        documentation = signature.getDocumentationComment(typeChecker);
        tags = signature.getJsDocTags();

        if (allSignatures.length > 1 && documentation.length === 0 && tags.length === 0) {
            documentation = allSignatures[0].getDocumentationComment(typeChecker);
            tags = allSignatures[0].getJsDocTags().filter(tag => tag.name !== "deprecated"); // should only include @deprecated JSDoc tag on the first overload (#49368)
        }
    }

    function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined) {
        const typeParameterParts = mapToDisplayParts(writer => {
            const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration, symbolDisplayNodeBuilderFlags);
            getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer);
        });
        addRange(displayParts, typeParameterParts);
    }
}

function isLocalVariableOrFunction(symbol: Symbol) {
    if (symbol.parent) {
        return false; // This is exported symbol
    }

    return forEach(symbol.declarations, declaration => {
        // Function expressions are local
        if (declaration.kind === SyntaxKind.FunctionExpression) {
            return true;
        }

        if (declaration.kind !== SyntaxKind.VariableDeclaration && declaration.kind !== SyntaxKind.FunctionDeclaration) {
            return false;
        }

        // If the parent is not sourceFile or module block it is local variable
        for (let parent = declaration.parent; !isFunctionBlock(parent); parent = parent.parent) {