function createSignatureHelpItems(candidates, bestSignature, argumentListInfo) {
                var applicableSpan = argumentListInfo.argumentsSpan;
                var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */;
                var invocation = argumentListInfo.invocation;
                var callTarget = ts.getInvokedExpression(invocation);
                var callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget);
                var callTargetDisplayParts = callTargetSymbol && ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
                var items = ts.map(candidates, function (candidateSignature) {
                    var signatureHelpParameters;
                    var prefixDisplayParts = [];
                    var suffixDisplayParts = [];
                    if (callTargetDisplayParts) {
                        ts.addRange(prefixDisplayParts, callTargetDisplayParts);
                    }
                    if (isTypeParameterList) {
                        prefixDisplayParts.push(ts.punctuationPart(25 /* LessThanToken */));
                        var typeParameters = candidateSignature.typeParameters;
                        signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
                        suffixDisplayParts.push(ts.punctuationPart(27 /* GreaterThanToken */));
                        var parameterParts = ts.mapToDisplayParts(function (writer) {
                            return typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation);
                        });
                        ts.addRange(suffixDisplayParts, parameterParts);
                    }
                    else {
                        var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                            return typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation);
                        });
                        ts.addRange(prefixDisplayParts, typeParameterParts);
                        prefixDisplayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                        var parameters = candidateSignature.parameters;
                        signatureHelpParameters = parameters.length > 0 ? ts.map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
                        suffixDisplayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                    }
                    var returnTypeParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation);
                    });
                    ts.addRange(suffixDisplayParts, returnTypeParts);
                    return {
                        isVariadic: candidateSignature.hasRestParameter,
                        prefixDisplayParts: prefixDisplayParts,
                        suffixDisplayParts: suffixDisplayParts,
                        separatorDisplayParts: [ts.punctuationPart(24 /* CommaToken */), ts.spacePart()],
                        parameters: signatureHelpParameters,
                        documentation: candidateSignature.getDocumentationComment()
                    };
                });
                var argumentIndex = argumentListInfo.argumentIndex;
                // argumentCount is the *apparent* number of arguments.
                var argumentCount = argumentListInfo.argumentCount;
                var selectedItemIndex = candidates.indexOf(bestSignature);
                if (selectedItemIndex < 0) {
                    selectedItemIndex = selectBestInvalidOverloadIndex(candidates, argumentCount);
                }
                ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex);
                return {
                    items: items,
                    applicableSpan: applicableSpan,
                    selectedItemIndex: selectedItemIndex,
                    argumentIndex: argumentIndex,
                    argumentCount: argumentCount
                };
                function createSignatureHelpParameterForParameter(parameter) {
                    var displayParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation);
                    });
                    return {
                        name: parameter.name,
                        documentation: parameter.getDocumentationComment(),
                        displayParts: displayParts,
                        isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration)
                    };
                }
                function createSignatureHelpParameterForTypeParameter(typeParameter) {
                    var displayParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation);
                    });
                    return {
                        name: typeParameter.symbol.name,
                        documentation: emptyArray,
                        displayParts: displayParts,
                        isOptional: false
                    };
                }
            }
The selectedItemIndex could be negative for several reasons.
    1. There are too many arguments for all of the overloads
    2. None of the overloads were type compatible
The solution here is to try to pick the best overload by picking
either the first one that has an appropriate number of parameters,
or the one with the most parameters.