Skip to content

Commit 9658b47

Browse files
authored
Fix inferFromUsage on index signatures (#25934)
* Fix inferFromUsage on index signatures 1. Check the argumentExpression to determine the index signature type. Previously, the code mistakenly checked the type of the element access itself, which never returned a good type. 2. If inference for the index signature type fails, substitute anyType. Previously, the code would create a bad index signature with an undefined type. 3. Add tests. Previously, there were no tests. * Fixing (1) means that number index signatures are now created. Previously, only string index signatures would be created. * Fixing (2) means that index signatures will be inferred from single usage like `return a[0]`. Previously, the refactoring would fail, perhaps because of a check when stringifying the index signature (I haven't tracked down why.) * Update fourslash test with improved inference
1 parent 7b4d13c commit 9658b47

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

src/services/codefixes/inferFromUsage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ namespace ts.codefix {
501501
return;
502502
}
503503
else {
504-
const indexType = checker.getTypeAtLocation(parent);
504+
const indexType = checker.getTypeAtLocation(parent.argumentExpression);
505505
const indexUsageContext = {};
506506
inferTypeFromContext(parent, checker, indexUsageContext);
507507
if (indexType.flags & TypeFlags.NumberLike) {
@@ -562,11 +562,11 @@ namespace ts.codefix {
562562
}
563563

564564
if (usageContext.numberIndexContext) {
565-
numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker)!, /*isReadonly*/ false); // TODO: GH#18217
565+
numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false);
566566
}
567567

568568
if (usageContext.stringIndexContext) {
569-
stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker)!, /*isReadonly*/ false);
569+
stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false);
570570
}
571571

572572
return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); // TODO: GH#18217
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @noImplicitAny: true
4+
////function f([|a |]) {
5+
//// return a[0] + 1;
6+
////}
7+
8+
verify.rangeAfterCodeFix("a: { [x: number]: number; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @noImplicitAny: true
4+
////function f([|a |]) {
5+
//// return a['hi'];
6+
////}
7+
8+
verify.rangeAfterCodeFix("a: { [x: string]: any; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference path="fourslash.ts" />
22

33
// @noImplicitAny: true
4-
//// function f(y, z = { p: y[
4+
//// function f([|y |], z = { p: y[
55

6-
verify.not.codeFixAvailable();
6+
verify.rangeAfterCodeFix("y: { [x: string]: any; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0);

0 commit comments

Comments
 (0)