diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 01aa861cabb76..07c1da2f7758f 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -4724,5 +4724,13 @@
"Generate types for all packages without types": {
"category": "Message",
"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
}
}
diff --git a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts
new file mode 100644
index 0000000000000..e6e8d759c6018
--- /dev/null
+++ b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts
@@ -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);
+ }
+}
diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json
index 66b1977ddc573..74be7988d2d98 100644
--- a/src/services/tsconfig.json
+++ b/src/services/tsconfig.json
@@ -43,6 +43,7 @@
"textChanges.ts",
"codeFixProvider.ts",
"refactorProvider.ts",
+ "codefixes/addConvertToUnknownForNonOverlappingTypes.ts",
"codefixes/addMissingInvocationForDecorator.ts",
"codefixes/annotateWithTypeFromJSDoc.ts",
"codefixes/convertFunctionToEs6Class.ts",
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes1.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes1.ts
new file mode 100644
index 0000000000000..df094bd5454a8
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes1.ts
@@ -0,0 +1,8 @@
+///
+
+////0 as string
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `0 as unknown as string`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes2.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes2.ts
new file mode 100644
index 0000000000000..138415aa79f3b
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes2.ts
@@ -0,0 +1,8 @@
+///
+
+////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`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes3.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes3.ts
new file mode 100644
index 0000000000000..7868f4b2fb9d5
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes3.ts
@@ -0,0 +1,8 @@
+///
+
+////["words"] as string
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `["words"] as unknown as string`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes4.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes4.ts
new file mode 100644
index 0000000000000..baaa8acae59c6
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes4.ts
@@ -0,0 +1,8 @@
+///
+
+////"words" as object
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `"words" as unknown as object`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes5.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes5.ts
new file mode 100644
index 0000000000000..24231e769d989
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes5.ts
@@ -0,0 +1,8 @@
+///
+
+////0
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `0`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes6.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes6.ts
new file mode 100644
index 0000000000000..e3349e95cd85e
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes6.ts
@@ -0,0 +1,8 @@
+///
+
+////0 * (4 + 3) / 100
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `0 * (4 + 3) / 100`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes7.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes7.ts
new file mode 100644
index 0000000000000..02b88d702ac7d
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes7.ts
@@ -0,0 +1,8 @@
+///
+
+////["words"]
+
+verify.codeFix({
+ description: "Add 'unknown' conversion for non-overlapping types",
+ newFileContent: `["words"]`
+});
diff --git a/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes8.ts b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes8.ts
new file mode 100644
index 0000000000000..38d4de370a217
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddConvertToUnknownForNonOverlappingTypes8.ts
@@ -0,0 +1,8 @@
+///
+
+////