mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add flag to change catch variables' default types to unknown (#41013)
* Add test case for 'useUnknownInCatchVariables'. * Add new 'useUnknownInCatchVariables' flag. * Accepted baselines. * Add test for catch variable explicitly typed as 'any'. * Accepted baselines. * Move option under 'strict'. * Accepted baselines. * 'useUnknownInCatchVariables' is strict in command line help.
This commit is contained in:
@@ -346,6 +346,7 @@ namespace ts {
|
||||
const strictOptionalProperties = getStrictOptionValue(compilerOptions, "strictOptionalProperties");
|
||||
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
|
||||
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
|
||||
const useUnknownInCatchVariables = getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables");
|
||||
const keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ObjectFlags.FreshLiteral;
|
||||
|
||||
@@ -9012,7 +9013,7 @@ namespace ts {
|
||||
if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
|
||||
const typeNode = getEffectiveTypeAnnotationNode(declaration);
|
||||
if (typeNode === undefined) {
|
||||
return anyType;
|
||||
return useUnknownInCatchVariables ? unknownType : anyType;
|
||||
}
|
||||
const type = getTypeOfNode(typeNode);
|
||||
// an errorType will make `checkTryStatement` issue an error
|
||||
|
||||
@@ -632,6 +632,15 @@ namespace ts {
|
||||
category: Diagnostics.Type_Checking,
|
||||
description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
|
||||
},
|
||||
{
|
||||
name: "useUnknownInCatchVariables",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Type_Checking,
|
||||
description: Diagnostics.Type_catch_clause_variables_as_unknown_instead_of_any,
|
||||
},
|
||||
{
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
|
||||
@@ -5198,6 +5198,10 @@
|
||||
"category": "Message",
|
||||
"code": 6802
|
||||
},
|
||||
"Type catch clause variables as 'unknown' instead of 'any'.": {
|
||||
"category": "Message",
|
||||
"code": 6803
|
||||
},
|
||||
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -6048,6 +6048,7 @@ namespace ts {
|
||||
/* @internal */ suppressOutputPathCheck?: boolean;
|
||||
target?: ScriptTarget; // TODO: GH#18217 frequently asserted as defined
|
||||
traceResolution?: boolean;
|
||||
useUnknownInCatchVariables?: boolean;
|
||||
resolveJsonModule?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to compute primary types search locations */
|
||||
|
||||
@@ -6088,6 +6088,7 @@ namespace ts {
|
||||
| "strictPropertyInitialization"
|
||||
| "strictOptionalProperties"
|
||||
| "alwaysStrict"
|
||||
| "useUnknownInCatchVariables"
|
||||
;
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
|
||||
@@ -2919,6 +2919,7 @@ declare namespace ts {
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
traceResolution?: boolean;
|
||||
useUnknownInCatchVariables?: boolean;
|
||||
resolveJsonModule?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to compute primary types search locations */
|
||||
|
||||
@@ -2919,6 +2919,7 @@ declare namespace ts {
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
traceResolution?: boolean;
|
||||
useUnknownInCatchVariables?: boolean;
|
||||
resolveJsonModule?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to compute primary types search locations */
|
||||
|
||||
@@ -120,7 +120,7 @@ class Foo {
|
||||
>Aborter : typeof Aborter
|
||||
|
||||
} catch (error) {
|
||||
>error : any
|
||||
>error : unknown
|
||||
|
||||
if (this.abortController !== undefined) {
|
||||
>this.abortController !== undefined : boolean
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"useUnknownInCatchVariables": true
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,10 @@ function f1() {
|
||||
>a : number
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
throw e;
|
||||
>e : any
|
||||
>e : unknown
|
||||
}
|
||||
finally {
|
||||
if (a != null && a.toFixed(0) == "123") {
|
||||
@@ -55,7 +55,7 @@ function f2() {
|
||||
>1 : 1
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -63,7 +63,7 @@ function f2() {
|
||||
>2 : 2
|
||||
|
||||
throw e;
|
||||
>e : any
|
||||
>e : unknown
|
||||
}
|
||||
finally {
|
||||
x; // 0 | 1 | 2
|
||||
@@ -87,7 +87,7 @@ function f3() {
|
||||
>1 : 1
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -118,7 +118,7 @@ function f4() {
|
||||
>1 : 1
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -149,7 +149,7 @@ function f5() {
|
||||
return;
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -178,7 +178,7 @@ function f6() {
|
||||
>1 : 1
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -211,7 +211,7 @@ function f7() {
|
||||
return;
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -324,7 +324,7 @@ function f10() {
|
||||
return;
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x = 2;
|
||||
>x = 2 : 2
|
||||
@@ -388,7 +388,7 @@ function f11() {
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x; // 0 | 1 | 2
|
||||
>x : 0 | 1 | 2
|
||||
@@ -466,7 +466,7 @@ function f12() {
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x; // 0 | 1 | 2
|
||||
>x : 0 | 1 | 2
|
||||
@@ -576,7 +576,7 @@ function t1() {
|
||||
>'x' : "x"
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
return null;
|
||||
>null : null
|
||||
@@ -626,7 +626,7 @@ function notallowed(arg: number) {
|
||||
finally { }
|
||||
}
|
||||
catch (err) {
|
||||
>err : any
|
||||
>err : unknown
|
||||
|
||||
state.tag;
|
||||
>state.tag : "one" | "two" | "three"
|
||||
@@ -770,7 +770,7 @@ function f21() {
|
||||
>x : 3 | 4 | 5
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
|
||||
x; // 0 | 1 | 2 | 3 | 4 | 5
|
||||
>x : 0 | 1 | 2 | 3 | 4 | 5
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
"noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -81,6 +81,7 @@
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ Options:
|
||||
--strictPropertyInitialization Enable strict checking of property initialization in classes.
|
||||
--strictOptionalProperties Enable strict checking of optional properties.
|
||||
--noImplicitThis Raise error on 'this' expressions with an implied 'any' type.
|
||||
--useUnknownInCatchVariables Type catch clause variables as 'unknown' instead of 'any'.
|
||||
--alwaysStrict Parse in strict mode and emit "use strict" for each source file.
|
||||
--noUnusedLocals Report errors on unused locals.
|
||||
--noUnusedParameters Report errors on unused parameters.
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ interface Array<T> { length: number; [n: number]: T; }
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "strictOptionalProperties": true, /* Enable strict checking of optional properties. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
|
||||
@@ -68,7 +68,7 @@ throw new Error('Unreachable')
|
||||
try {
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
>e : unknown
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
tests/cases/compiler/useUnknownInCatchVariables01.ts(6,12): error TS2339: Property 'toUpperCase' does not exist on type 'unknown'.
|
||||
tests/cases/compiler/useUnknownInCatchVariables01.ts(7,10): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.
|
||||
tests/cases/compiler/useUnknownInCatchVariables01.ts(8,10): error TS2349: This expression is not callable.
|
||||
Type '{}' has no call signatures.
|
||||
|
||||
|
||||
==== tests/cases/compiler/useUnknownInCatchVariables01.ts (3 errors) ====
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'toUpperCase' does not exist on type 'unknown'.
|
||||
void e++;
|
||||
~
|
||||
!!! error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.
|
||||
void e();
|
||||
~
|
||||
!!! error TS2349: This expression is not callable.
|
||||
!!! error TS2349: Type '{}' has no call signatures.
|
||||
|
||||
if (typeof e === "string") {
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
e.stack?.toUpperCase();
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
e.toExponential();
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e: any) {
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
void e.toExponential();
|
||||
void e();
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//// [useUnknownInCatchVariables01.ts]
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
void e++;
|
||||
void e();
|
||||
|
||||
if (typeof e === "string") {
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
e.stack?.toUpperCase();
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
e.toExponential();
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e: any) {
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
void e.toExponential();
|
||||
void e();
|
||||
}
|
||||
|
||||
//// [useUnknownInCatchVariables01.js]
|
||||
var _a;
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
void e++;
|
||||
void e();
|
||||
if (typeof e === "string") {
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
(_a = e.stack) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
e.toExponential();
|
||||
e++;
|
||||
}
|
||||
}
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
void e.toExponential();
|
||||
void e();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
=== tests/cases/compiler/useUnknownInCatchVariables01.ts ===
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
void e++;
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
void e();
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
if (typeof e === "string") {
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>e.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
e.stack?.toUpperCase();
|
||||
>e.stack?.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
|
||||
>e.stack : Symbol(Error.stack, Decl(lib.es5.d.ts, --, --))
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
>stack : Symbol(Error.stack, Decl(lib.es5.d.ts, --, --))
|
||||
>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
|
||||
e.toExponential();
|
||||
>e.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
e++;
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 3, 7))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e: any) {
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 27, 7))
|
||||
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 27, 7))
|
||||
|
||||
void e.toExponential();
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 27, 7))
|
||||
|
||||
void e();
|
||||
>e : Symbol(e, Decl(useUnknownInCatchVariables01.ts, 27, 7))
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
=== tests/cases/compiler/useUnknownInCatchVariables01.ts ===
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
>e : unknown
|
||||
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
>void e.toUpperCase() : undefined
|
||||
>e.toUpperCase() : any
|
||||
>e.toUpperCase : any
|
||||
>e : unknown
|
||||
>toUpperCase : any
|
||||
|
||||
void e++;
|
||||
>void e++ : undefined
|
||||
>e++ : number
|
||||
>e : unknown
|
||||
|
||||
void e();
|
||||
>void e() : undefined
|
||||
>e() : any
|
||||
>e : unknown
|
||||
|
||||
if (typeof e === "string") {
|
||||
>typeof e === "string" : boolean
|
||||
>typeof e : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>e : unknown
|
||||
>"string" : "string"
|
||||
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
>console.log(e.toUpperCase()) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>e.toUpperCase() : string
|
||||
>e.toUpperCase : () => string
|
||||
>e : string
|
||||
>toUpperCase : () => string
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
>e instanceof Error : boolean
|
||||
>e : unknown
|
||||
>Error : ErrorConstructor
|
||||
|
||||
e.stack?.toUpperCase();
|
||||
>e.stack?.toUpperCase() : string
|
||||
>e.stack?.toUpperCase : () => string
|
||||
>e.stack : string
|
||||
>e : Error
|
||||
>stack : string
|
||||
>toUpperCase : () => string
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
>typeof e === "number" : boolean
|
||||
>typeof e : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>e : unknown
|
||||
>"number" : "number"
|
||||
|
||||
e.toExponential();
|
||||
>e.toExponential() : string
|
||||
>e.toExponential : (fractionDigits?: number) => string
|
||||
>e : number
|
||||
>toExponential : (fractionDigits?: number) => string
|
||||
|
||||
e++;
|
||||
>e++ : number
|
||||
>e : number
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e: any) {
|
||||
>e : any
|
||||
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
>void e.toUpperCase() : undefined
|
||||
>e.toUpperCase() : any
|
||||
>e.toUpperCase : any
|
||||
>e : any
|
||||
>toUpperCase : any
|
||||
|
||||
void e.toExponential();
|
||||
>void e.toExponential() : undefined
|
||||
>e.toExponential() : any
|
||||
>e.toExponential : any
|
||||
>e : any
|
||||
>toExponential : any
|
||||
|
||||
void e();
|
||||
>void e() : undefined
|
||||
>e() : any
|
||||
>e : any
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// @useUnknownInCatchVariables: true
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e) {
|
||||
// error!
|
||||
void e.toUpperCase();
|
||||
void e++;
|
||||
void e();
|
||||
|
||||
if (typeof e === "string") {
|
||||
// works!
|
||||
// We've narrowed 'e' down to the type 'string'.
|
||||
console.log(e.toUpperCase());
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
e.stack?.toUpperCase();
|
||||
}
|
||||
if (typeof e === "number") {
|
||||
e.toExponential();
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// ...
|
||||
}
|
||||
catch (e: any) {
|
||||
// All are allowed.
|
||||
void e.toUpperCase();
|
||||
void e.toExponential();
|
||||
void e();
|
||||
}
|
||||
Reference in New Issue
Block a user