Merge pull request #28281 from ryanclarke/master
Add codefix for 'convert to unknown' diagnostic
This commit is contained in:
commit
2585ccbe39
12 changed files with 114 additions and 0 deletions
|
@ -4756,5 +4756,13 @@
|
||||||
"Generate types for all packages without types": {
|
"Generate types for all packages without types": {
|
||||||
"category": "Message",
|
"category": "Message",
|
||||||
"code": 95068
|
"code": 95068
|
||||||
|
},
|
||||||
|
"Add 'unknown' conversion for non-overlapping types": {
|
||||||
|
"category": "Message",
|
||||||
|
"code": 95069
|
||||||
|
},
|
||||||
|
"Add 'unknown' to all conversions of non-overlapping types": {
|
||||||
|
"category": "Message",
|
||||||
|
"code": 95070
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* @internal */
|
||||||
|
namespace ts.codefix {
|
||||||
|
const fixId = "addConvertToUnknownForNonOverlappingTypes";
|
||||||
|
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];
|
||||||
|
registerCodeFix({
|
||||||
|
errorCodes,
|
||||||
|
getCodeActions: (context) => {
|
||||||
|
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start));
|
||||||
|
return [createCodeFixAction(fixId, changes, Diagnostics.Add_unknown_conversion_for_non_overlapping_types, fixId, Diagnostics.Add_unknown_to_all_conversions_of_non_overlapping_types)];
|
||||||
|
},
|
||||||
|
fixIds: [fixId],
|
||||||
|
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)),
|
||||||
|
});
|
||||||
|
|
||||||
|
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
|
||||||
|
const token = getTokenAtPosition(sourceFile, pos);
|
||||||
|
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
|
||||||
|
const replacement = isAsExpression(assertion)
|
||||||
|
? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword))
|
||||||
|
: createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
|
||||||
|
changeTracker.replaceNode(sourceFile, assertion.expression, replacement);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,7 @@
|
||||||
"textChanges.ts",
|
"textChanges.ts",
|
||||||
"codeFixProvider.ts",
|
"codeFixProvider.ts",
|
||||||
"refactorProvider.ts",
|
"refactorProvider.ts",
|
||||||
|
"codefixes/addConvertToUnknownForNonOverlappingTypes.ts",
|
||||||
"codefixes/addMissingInvocationForDecorator.ts",
|
"codefixes/addMissingInvocationForDecorator.ts",
|
||||||
"codefixes/annotateWithTypeFromJSDoc.ts",
|
"codefixes/annotateWithTypeFromJSDoc.ts",
|
||||||
"codefixes/inferFromUsage.ts",
|
"codefixes/inferFromUsage.ts",
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////0 as string
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `0 as unknown as string`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////0 * (4 + 3) / 100 as string
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `0 * (4 + 3) / 100 as unknown as string`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////["words"] as string
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `["words"] as unknown as string`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////"words" as object
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `"words" as unknown as object`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////<string>0
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `<string><unknown>0`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////<string>0 * (4 + 3) / 100
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `<string><unknown>0 * (4 + 3) / 100`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////<string>["words"]
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `<string><unknown>["words"]`
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////<object>"words"
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add 'unknown' conversion for non-overlapping types",
|
||||||
|
newFileContent: `<object><unknown>"words"`
|
||||||
|
});
|
|
@ -0,0 +1,18 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////const s1 = 1 as string;
|
||||||
|
////const o1 = s + " word" as object;
|
||||||
|
////
|
||||||
|
////const s2 = <string>2;
|
||||||
|
////const o2 = <object>s2;
|
||||||
|
|
||||||
|
verify.codeFixAll({
|
||||||
|
fixId: "addConvertToUnknownForNonOverlappingTypes",
|
||||||
|
fixAllDescription: "Add 'unknown' to all conversions of non-overlapping types",
|
||||||
|
newFileContent:
|
||||||
|
`const s1 = 1 as unknown as string;
|
||||||
|
const o1 = s + " word" as unknown as object;
|
||||||
|
|
||||||
|
const s2 = <string><unknown>2;
|
||||||
|
const o2 = <object><unknown>s2;`
|
||||||
|
});
|
Loading…
Reference in a new issue