Skip to content

Commit ef83109

Browse files
Prefer a likely literal over anonymous type in --noImplicitAny codefixes (microsoft#36015)
* Prefer a likely literal over anonymous type in --noImplicitAny codefixes Before trying to make an anonymous type for a type's usage, we'll first check if there is exactly one builtin primitive the usage is assignable to, and use it if so. Right now that's only `number` and `string` because `boolean` has no distinguishable members. A couple of implementation details: * `tryInsertTypeAnnotation` needed to know to insert a type _after_ a node's `exclamationToken` if it exists * This code area was written before `??` 😉 * Used unknown/any instead of void when applicable * Fix little whitespace change in tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts * Undid some now-unnecessary unknown additions * Took advice on restricting void to just call expressions
1 parent f248567 commit ef83109

6 files changed

+28
-8
lines changed

src/services/codefixes/inferFromUsage.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ namespace ts.codefix {
603603

604604
switch (node.parent.kind) {
605605
case SyntaxKind.ExpressionStatement:
606-
addCandidateType(usage, checker.getVoidType());
606+
inferTypeFromExpressionStatement(node, usage);
607607
break;
608608
case SyntaxKind.PostfixUnaryExpression:
609609
usage.isNumber = true;
@@ -661,6 +661,10 @@ namespace ts.codefix {
661661
}
662662
}
663663

664+
function inferTypeFromExpressionStatement(node: Expression, usage: Usage): void {
665+
addCandidateType(usage, isCallExpression(node) ? checker.getVoidType() : checker.getAnyType());
666+
}
667+
664668
function inferTypeFromPrefixUnaryExpression(node: PrefixUnaryExpression, usage: Usage): void {
665669
switch (node.operator) {
666670
case SyntaxKind.PlusPlusToken:
@@ -960,10 +964,7 @@ namespace ts.codefix {
960964
if (usage.numberIndex) {
961965
types.push(checker.createArrayType(combineFromUsage(usage.numberIndex)));
962966
}
963-
if (usage.properties && usage.properties.size
964-
|| usage.calls && usage.calls.length
965-
|| usage.constructs && usage.constructs.length
966-
|| usage.stringIndex) {
967+
if (usage.properties?.size || usage.calls?.length || usage.constructs?.length || usage.stringIndex) {
967968
types.push(inferStructuralType(usage));
968969
}
969970

src/services/textChanges.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ namespace ts.textChanges {
434434
}
435435
}
436436
else {
437-
endNode = node.kind !== SyntaxKind.VariableDeclaration && node.questionToken ? node.questionToken : node.name;
437+
endNode = (node.kind === SyntaxKind.VariableDeclaration ? node.exclamationToken : node.questionToken) ?? node.name;
438438
}
439439

440440
this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @noImplicitAny: true
4+
//// function foo([|text |]) {
5+
//// text.length;
6+
//// text.indexOf("z");
7+
//// text.charAt(0);
8+
//// }
9+
10+
verify.rangeAfterCodeFix("text: string", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0);

tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
//// return x.y.z
1313
////}
1414

15-
verify.rangeAfterCodeFix("a: { b: { c: void; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0);
15+
verify.rangeAfterCodeFix("a: { b: { c: any; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0);

tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ verify.codeFix({
2121
index: 0,
2222
newFileContent:
2323
`/**
24-
* @param {{ b: { c: void; }; }} a
24+
* @param {{ b: { c: any; }; }} a
2525
* @param {{ n: () => number; }} m
2626
* @param {{ y: { z: number[]; }; }} x
2727
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @noImplicitAny: true
4+
//// let [|text! |];
5+
//// text.length;
6+
//// text.indexOf("z");
7+
//// text.charAt(0);
8+
9+
verify.rangeAfterCodeFix("text!: string", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0);

0 commit comments

Comments
 (0)