Skip to content

Commit

Permalink
recommend set if el is on RHS of assignment else get
Browse files Browse the repository at this point in the history
  • Loading branch information
collin5 committed Apr 29, 2019
1 parent 013c5bb commit 7c5023a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
40 changes: 25 additions & 15 deletions src/compiler/checker.ts
Expand Up @@ -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));
Expand Down Expand Up @@ -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;
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/utilities.ts
Expand Up @@ -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";
}
Expand Down

0 comments on commit 7c5023a

Please sign in to comment.