From 0c1730a21871762c392f8d6862adfc1005743edd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 17 Oct 2017 16:51:22 -0700 Subject: [PATCH] Fix #19257: Ensure a generated signature has a return type (#19264) * Fix #19257: Ensure a generated signature has a return type * Ensure generated properties have types * Use the same context for multiple inferences to the same property access --- src/services/codefixes/inferFromUsage.ts | 6 +++--- .../cases/fourslash/codeFixInferFromUsageCall.ts | 8 ++++++++ .../codeFixInferFromUsagePropertyAccess.ts | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/codeFixInferFromUsageCall.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 046eb915c1..b952cc5a98 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -521,7 +521,7 @@ namespace ts.codefix { if (!usageContext.properties) { usageContext.properties = createUnderscoreEscapedMap(); } - const propertyUsageContext = {}; + const propertyUsageContext = usageContext.properties.get(name) || { }; inferTypeFromContext(parent, checker, propertyUsageContext); usageContext.properties.set(name, propertyUsageContext); } @@ -575,7 +575,7 @@ namespace ts.codefix { if (usageContext.properties) { usageContext.properties.forEach((context, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = getTypeFromUsageContext(context, checker); + symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType(); members.set(name, symbol); }); } @@ -636,7 +636,7 @@ namespace ts.codefix { symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); parameters.push(symbol); } - const returnType = getTypeFromUsageContext(callContext.returnType, checker); + const returnType = getTypeFromUsageContext(callContext.returnType, checker) || checker.getVoidType(); return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } diff --git a/tests/cases/fourslash/codeFixInferFromUsageCall.ts b/tests/cases/fourslash/codeFixInferFromUsageCall.ts new file mode 100644 index 0000000000..e74b6faf7d --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageCall.ts @@ -0,0 +1,8 @@ +/// + +// @noImplicitAny: true +////function wat([|b |]) { +//// b(); +////} + +verify.rangeAfterCodeFix("b: () => void"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts new file mode 100644 index 0000000000..c8b85ee11e --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts @@ -0,0 +1,15 @@ +/// + +// @noImplicitAny: true +////function foo([|a, m, x |]) { +//// a.b.c; +//// +//// var numeric = 0; +//// numeric = m.n(); +//// +//// x.y.z +//// x.y.z.push(0); +//// return x.y.z +////} + +verify.rangeAfterCodeFix("a: { b: { c: any; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); \ No newline at end of file