From 02630273a279f5febe621261e44ab2fc13e85c8e Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 11:37:31 -0700 Subject: [PATCH] codeFixInferFromUsage: Assume that using `x[0]` means that `x` is an array (#26739) * codeFixInferFromUsage: Assume that using `x[0]` means that `x` is an array * Remove unnecessary '||' with non-falsy LHS If only there were some kind of type-checker for JavaScript that could detect this sort of thing --- src/services/codefixes/inferFromUsage.ts | 20 ++++++++++--------- ...deFixInferFromUsageNumberIndexSignature.ts | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index f7b5edc5ca..17b3469f0b 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -534,17 +534,19 @@ namespace ts.codefix { else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) { return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!); } - else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) { + else if (usageContext.numberIndexContext) { + return checker.createArrayType(recur(usageContext.numberIndexContext)); + } + else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) { const members = createUnderscoreEscapedMap(); const callSignatures: Signature[] = []; const constructSignatures: Signature[] = []; let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; if (usageContext.properties) { usageContext.properties.forEach((context, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType(); + symbol.type = recur(context); members.set(name, symbol); }); } @@ -561,19 +563,19 @@ namespace ts.codefix { } } - if (usageContext.numberIndexContext) { - numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false); - } - if (usageContext.stringIndexContext) { - stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false); + stringIndexInfo = checker.createIndexInfo(recur(usageContext.stringIndexContext), /*isReadonly*/ false); } - return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); // TODO: GH#18217 + return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 } else { return undefined; } + + function recur(innerContext: UsageContext): Type { + return getTypeFromUsageContext(innerContext, checker) || checker.getAnyType(); + } } function getParameterTypeFromCallContexts(parameterIndex: number, callContexts: CallContext[], isRestParameter: boolean, checker: TypeChecker) { diff --git a/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts b/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts index cf031bd017..2587cc79dc 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts @@ -5,4 +5,4 @@ //// return a[0] + 1; ////} -verify.rangeAfterCodeFix("a: { [x: number]: number; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); +verify.rangeAfterCodeFix("a: number[]",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0);