Skip to content

Commit b5afe9c

Browse files
authored
feat(typescript-estree): support type annotations on catch clauses (typescript-eslint#2306)
1 parent cbaac77 commit b5afe9c

File tree

9 files changed

+1534
-12
lines changed

9 files changed

+1534
-12
lines changed

packages/parser/tests/lib/__snapshots__/typescript.ts.snap

Lines changed: 456 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
try {
2+
3+
} catch (e: any) {
4+
5+
}
6+
7+
try {
8+
9+
} catch (e: unknown) {
10+
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
try {
2+
3+
} catch (e: string) {
4+
5+
}

packages/typescript-estree/src/convert.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,21 @@ export class Converter {
258258
return result as T;
259259
}
260260

261+
private convertBindingNameWithTypeAnnotation(
262+
name: ts.BindingName,
263+
tsType: ts.TypeNode | undefined,
264+
parent?: ts.Node,
265+
): TSESTree.BindingName {
266+
const id = this.convertPattern(name);
267+
268+
if (tsType) {
269+
id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
270+
this.fixParentLocation(id, id.typeAnnotation.range);
271+
}
272+
273+
return id;
274+
}
275+
261276
/**
262277
* Converts a child into a type annotation. This creates an intermediary
263278
* TypeAnnotation node to match what Flow does.
@@ -267,12 +282,12 @@ export class Converter {
267282
*/
268283
private convertTypeAnnotation(
269284
child: ts.TypeNode,
270-
parent: ts.Node,
285+
parent: ts.Node | undefined,
271286
): TSESTree.TSTypeAnnotation {
272287
// in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
273288
const offset =
274-
parent.kind === SyntaxKind.FunctionType ||
275-
parent.kind === SyntaxKind.ConstructorType
289+
parent?.kind === SyntaxKind.FunctionType ||
290+
parent?.kind === SyntaxKind.ConstructorType
276291
? 2
277292
: 1;
278293
const annotationStartCol = child.getFullStart() - offset;
@@ -697,7 +712,10 @@ export class Converter {
697712
return this.createNode<TSESTree.CatchClause>(node, {
698713
type: AST_NODE_TYPES.CatchClause,
699714
param: node.variableDeclaration
700-
? this.convertChild(node.variableDeclaration.name)
715+
? this.convertBindingNameWithTypeAnnotation(
716+
node.variableDeclaration.name,
717+
node.variableDeclaration.type,
718+
)
701719
: null,
702720
body: this.convertChild(node.block),
703721
});
@@ -805,21 +823,18 @@ export class Converter {
805823
case SyntaxKind.VariableDeclaration: {
806824
const result = this.createNode<TSESTree.VariableDeclarator>(node, {
807825
type: AST_NODE_TYPES.VariableDeclarator,
808-
id: this.convertPattern(node.name),
826+
id: this.convertBindingNameWithTypeAnnotation(
827+
node.name,
828+
node.type,
829+
node,
830+
),
809831
init: this.convertChild(node.initializer),
810832
});
811833

812834
if (node.exclamationToken) {
813835
result.definite = true;
814836
}
815837

816-
if (node.type) {
817-
result.id.typeAnnotation = this.convertTypeAnnotation(
818-
node.type,
819-
node,
820-
);
821-
this.fixParentLocation(result.id, result.id.typeAnnotation.range);
822-
}
823838
return result;
824839
}
825840

packages/typescript-estree/src/semantic-or-syntactic-errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ function whitelistSupportedDiagnostics(
8181
case 1175: // "'implements' clause already seen."
8282
case 1176: // "Interface declaration cannot have 'implements' clause."
8383
case 1190: // "The variable declaration of a 'for...of' statement cannot have an initializer."
84+
case 1196: // "Catch clause variable type annotation must be 'any' or 'unknown' if specified."
8485
case 1200: // "Line terminator not permitted before arrow."
8586
case 1206: // "Decorators are not valid here."
8687
case 1211: // "A class declaration without the 'default' modifier must have a name."

packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ tester.addFixturePatternConfig('typescript/basics', {
418418
* babel uses a representation that does not match the ESTree spec: https://github.com/estree/estree/pull/205
419419
*/
420420
'export-star-as-ns-from',
421+
/**
422+
* TS 4.0 catch clause with type annotation
423+
* Not supported in babel yet
424+
*/
425+
'catch-clause-with-annotation',
426+
'catch-clause-with-invalid-annotation',
421427
],
422428
ignoreSourceType: [
423429
/**

packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,17 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e
17361736

17371737
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/cast-as-simple.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
17381738

1739+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-clause-with-annotation.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1740+
1741+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-clause-with-invalid-annotation.src 1`] = `
1742+
Object {
1743+
"column": 12,
1744+
"index": 19,
1745+
"lineNumber": 3,
1746+
"message": "Catch clause variable type annotation must be 'any' or 'unknown' if specified.",
1747+
}
1748+
`;
1749+
17391750
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-abstract.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
17401751

17411752
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-declare.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy