From 7c5023ad0138c11a920506d3a798b8b4af7886d4 Mon Sep 17 00:00:00 2001 From: Collins Abitekaniza Date: Tue, 30 Apr 2019 02:09:29 +0300 Subject: [PATCH] recommend set if el is on RHS of assignment else get --- src/compiler/checker.ts | 40 ++++++++++++++++++++++++--------------- src/compiler/utilities.ts | 10 ++++++++++ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7050ef60f04cd..6bde018792093 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10114,9 +10114,9 @@ namespace ts { } } else { - const suggestions = getSuggestionsForNonexistentIndexSignature(objectType); - if (suggestions) { - error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestions); + const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression); + if (suggestion !== undefined) { + error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion); } else { error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType)); @@ -20055,23 +20055,33 @@ namespace ts { return suggestion && symbolName(suggestion); } - function getSuggestionsForNonexistentIndexSignature(objectType: Type): string | undefined { - let suggestions: string | undefined; - const props = [ - getPropertyOfObjectType(objectType, <__String>"get"), - getPropertyOfObjectType(objectType, <__String>"set") - ]; - - for (const prop of props) { + function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression): string | undefined { + // check if object type has setter or getter + const hasProp = (name: "set" | "get", argCount = 1) => { + const prop = getPropertyOfObjectType(objectType, <__String>name); if (prop) { const s = getSingleCallSignature(getTypeOfSymbol(prop)); - if (s && getMinArgumentCount(s) === 1 && typeToString(getTypeAtPosition(s, 0)) === "string") { - const suggestion = symbolToString(objectType.symbol) + "." + symbolToString(prop); - suggestions = (!suggestions) ? suggestion : suggestions.concat(" or " + suggestion); + if (s && getMinArgumentCount(s) === argCount && typeToString(getTypeAtPosition(s, 0)) === "string") { + return true; } } + return false; + }; + + const suggestedMethod = isAssignmentTarget(expr) ? "set" : "get"; + if (!hasProp(suggestedMethod)) { + return undefined; + } + + let suggestion = tryGetPropertyAccessOrIdentifierToString(expr); + if (suggestion === undefined) { + suggestion = suggestedMethod; } - return suggestions; + else { + suggestion += "." + suggestedMethod; + } + + return suggestion; } /** diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 188f2f8630209..45dc980296be7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3960,6 +3960,16 @@ namespace ts { return isPropertyAccessExpression(node) && isEntityNameExpression(node.expression); } + export function tryGetPropertyAccessOrIdentifierToString(expr: Expression): string | undefined { + if (isPropertyAccessExpression(expr)) { + return tryGetPropertyAccessOrIdentifierToString(expr.expression) + "." + expr.name; + } + if (isIdentifier(expr)) { + return unescapeLeadingUnderscores(expr.escapedText); + } + return undefined; + } + export function isPrototypeAccess(node: Node): node is PropertyAccessExpression { return isPropertyAccessExpression(node) && node.name.escapedText === "prototype"; }