diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2eed799837918..3c968bd2aedbc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9203,7 +9203,13 @@ namespace ts { } } else { - error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType)); + 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); + } + else { + error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType)); + } } } } @@ -18129,6 +18135,25 @@ 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) { + 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); + } + } + } + return suggestions; + } + /** * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough. * Names less than length 3 only check for case-insensitive equality, not levenshtein distance. diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 16b064f255cc4..cb9a420373e6e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3941,6 +3941,10 @@ "category": "Error", "code": 7041 }, + "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}' ?": { + "category": "Error", + "code": 7042 + }, "You cannot rename this element.": { "category": "Error", "code": 8000