Skip to content

Commit 2585ccb

Browse files
Merge pull request #28281 from ryanclarke/master
Add codefix for 'convert to unknown' diagnostic
2 parents e335a36 + ecb88f5 commit 2585ccb

12 files changed

+114
-0
lines changed

src/compiler/diagnosticMessages.json

+8
Original file line numberDiff line numberDiff line change
@@ -4756,5 +4756,13 @@
47564756
"Generate types for all packages without types": {
47574757
"category": "Message",
47584758
"code": 95068
4759+
},
4760+
"Add 'unknown' conversion for non-overlapping types": {
4761+
"category": "Message",
4762+
"code": 95069
4763+
},
4764+
"Add 'unknown' to all conversions of non-overlapping types": {
4765+
"category": "Message",
4766+
"code": 95070
47594767
}
47604768
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* @internal */
2+
namespace ts.codefix {
3+
const fixId = "addConvertToUnknownForNonOverlappingTypes";
4+
const errorCodes = [Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first.code];
5+
registerCodeFix({
6+
errorCodes,
7+
getCodeActions: (context) => {
8+
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start));
9+
return [createCodeFixAction(fixId, changes, Diagnostics.Add_unknown_conversion_for_non_overlapping_types, fixId, Diagnostics.Add_unknown_to_all_conversions_of_non_overlapping_types)];
10+
},
11+
fixIds: [fixId],
12+
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)),
13+
});
14+
15+
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
16+
const token = getTokenAtPosition(sourceFile, pos);
17+
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
18+
const replacement = isAsExpression(assertion)
19+
? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword))
20+
: createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
21+
changeTracker.replaceNode(sourceFile, assertion.expression, replacement);
22+
}
23+
}

src/services/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"textChanges.ts",
4444
"codeFixProvider.ts",
4545
"refactorProvider.ts",
46+
"codefixes/addConvertToUnknownForNonOverlappingTypes.ts",
4647
"codefixes/addMissingInvocationForDecorator.ts",
4748
"codefixes/annotateWithTypeFromJSDoc.ts",
4849
"codefixes/inferFromUsage.ts",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////0 as string
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `0 as unknown as string`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////0 * (4 + 3) / 100 as string
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `0 * (4 + 3) / 100 as unknown as string`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////["words"] as string
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `["words"] as unknown as string`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////"words" as object
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `"words" as unknown as object`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////<string>0
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `<string><unknown>0`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////<string>0 * (4 + 3) / 100
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `<string><unknown>0 * (4 + 3) / 100`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////<string>["words"]
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `<string><unknown>["words"]`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////<object>"words"
4+
5+
verify.codeFix({
6+
description: "Add 'unknown' conversion for non-overlapping types",
7+
newFileContent: `<object><unknown>"words"`
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////const s1 = 1 as string;
4+
////const o1 = s + " word" as object;
5+
////
6+
////const s2 = <string>2;
7+
////const o2 = <object>s2;
8+
9+
verify.codeFixAll({
10+
fixId: "addConvertToUnknownForNonOverlappingTypes",
11+
fixAllDescription: "Add 'unknown' to all conversions of non-overlapping types",
12+
newFileContent:
13+
`const s1 = 1 as unknown as string;
14+
const o1 = s + " word" as unknown as object;
15+
16+
const s2 = <string><unknown>2;
17+
const o2 = <object><unknown>s2;`
18+
});

0 commit comments

Comments
 (0)