Skip to content

Commit 2ebfb21

Browse files
armano2bradzacher
andauthored
feat: TypeScript 4.2 syntax support (typescript-eslint#3112)
* chore(typescript-estree): update @babel/parser to 7.13.4 * feat: update typescript to ~4.2 * fix(typescript-estree): add support for JSXNamespacedName node * fix(typescript-estree): correct tsNodeToESTreeNodeMap * fix(typescript-estree): add support for ThisKeyword as JSXNamespaceOrIdentifier helper Co-authored-by: Brad Zacher <brad.zacher@gmail.com>
1 parent cf86f42 commit 2ebfb21

26 files changed

+2854
-182
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ The latest version under the `canary` tag **(latest commit to master)** is:
233233

234234
## Supported TypeScript Version
235235

236-
**The version range of TypeScript currently supported by this parser is `>=3.3.1 <4.2.0`.**
236+
**The version range of TypeScript currently supported by this parser is `>=3.3.1 <4.3.0`.**
237237

238238
These versions are what we test against.
239239

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@
112112
"ts-jest": "^26.5.1",
113113
"ts-node": "^9.0.0",
114114
"tslint": "^6.1.3",
115-
"typescript": ">=3.3.1 <4.2.0"
115+
"typescript": ">=3.3.1 <4.3.0"
116116
},
117117
"resolutions": {
118-
"typescript": "4.1.5"
118+
"typescript": "4.2.2"
119119
}
120120
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<this:bar />;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const x: abstract new () => void;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const x: new () => void;

packages/types/src/ast-node-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum AST_NODE_TYPES {
4747
JSXFragment = 'JSXFragment',
4848
JSXIdentifier = 'JSXIdentifier',
4949
JSXMemberExpression = 'JSXMemberExpression',
50+
JSXNamespacedName = 'JSXNamespacedName',
5051
JSXOpeningElement = 'JSXOpeningElement',
5152
JSXOpeningFragment = 'JSXOpeningFragment',
5253
JSXSpreadAttribute = 'JSXSpreadAttribute',

packages/types/src/ts-estree.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export type Node =
188188
| JSXFragment
189189
| JSXIdentifier
190190
| JSXMemberExpression
191+
| JSXNamespacedName
191192
| JSXOpeningElement
192193
| JSXOpeningFragment
193194
| JSXSpreadAttribute
@@ -374,6 +375,7 @@ export type Expression =
374375
| SequenceExpression
375376
| SpreadElement
376377
| TSAsExpression
378+
| TSTypeAssertion
377379
| TSUnaryExpression
378380
| YieldExpression;
379381
export type ForInitialiser = Expression | VariableDeclaration;
@@ -398,7 +400,10 @@ export type JSXExpression =
398400
| JSXEmptyExpression
399401
| JSXSpreadChild
400402
| JSXExpressionContainer;
401-
export type JSXTagNameExpression = JSXIdentifier | JSXMemberExpression;
403+
export type JSXTagNameExpression =
404+
| JSXIdentifier
405+
| JSXMemberExpression
406+
| JSXNamespacedName;
402407
export type LeftHandSideExpression =
403408
| CallExpression
404409
| ClassExpression
@@ -1024,7 +1029,7 @@ export interface ImportSpecifier extends BaseNode {
10241029

10251030
export interface JSXAttribute extends BaseNode {
10261031
type: AST_NODE_TYPES.JSXAttribute;
1027-
name: JSXIdentifier;
1032+
name: JSXIdentifier | JSXNamespacedName;
10281033
value: Literal | JSXExpression | null;
10291034
}
10301035

@@ -1071,6 +1076,12 @@ export interface JSXMemberExpression extends BaseNode {
10711076
property: JSXIdentifier;
10721077
}
10731078

1079+
export interface JSXNamespacedName extends BaseNode {
1080+
type: AST_NODE_TYPES.JSXNamespacedName;
1081+
namespace: JSXIdentifier;
1082+
name: JSXIdentifier;
1083+
}
1084+
10741085
export interface JSXOpeningElement extends BaseNode {
10751086
type: AST_NODE_TYPES.JSXOpeningElement;
10761087
typeParameters?: TSTypeParameterInstantiation;
@@ -1340,6 +1351,7 @@ export interface TSConditionalType extends BaseNode {
13401351

13411352
export interface TSConstructorType extends FunctionSignatureBase {
13421353
type: AST_NODE_TYPES.TSConstructorType;
1354+
abstract: boolean;
13431355
}
13441356

13451357
export interface TSConstructSignatureDeclaration extends FunctionSignatureBase {

packages/typescript-estree/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
},
5252
"devDependencies": {
5353
"@babel/code-frame": "^7.12.13",
54-
"@babel/parser": "^7.12.16",
55-
"@babel/types": "^7.12.13",
54+
"@babel/parser": "^7.13.4",
55+
"@babel/types": "^7.13.0",
5656
"@types/babel__code-frame": "*",
5757
"@types/debug": "*",
5858
"@types/glob": "*",

packages/typescript-estree/src/convert.ts

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,46 @@ export class Converter {
517517
return result;
518518
}
519519

520+
private convertJSXIdentifier(
521+
node: ts.Identifier | ts.ThisExpression,
522+
): TSESTree.JSXIdentifier {
523+
const result = this.createNode<TSESTree.JSXIdentifier>(node, {
524+
type: AST_NODE_TYPES.JSXIdentifier,
525+
name: node.getText(),
526+
});
527+
this.registerTSNodeInNodeMap(node, result);
528+
return result;
529+
}
530+
531+
private convertJSXNamespaceOrIdentifier(
532+
node: ts.Identifier | ts.ThisExpression,
533+
): TSESTree.JSXIdentifier | TSESTree.JSXNamespacedName {
534+
const text = node.getText();
535+
const colonIndex = text.indexOf(':');
536+
// this is intentional we can ignore conversion if `:` is in first character
537+
if (colonIndex > 0) {
538+
const range = getRange(node, this.ast);
539+
const result = this.createNode<TSESTree.JSXNamespacedName>(node, {
540+
type: AST_NODE_TYPES.JSXNamespacedName,
541+
namespace: this.createNode<TSESTree.JSXIdentifier>(node, {
542+
type: AST_NODE_TYPES.JSXIdentifier,
543+
name: text.slice(0, colonIndex),
544+
range: [range[0], range[0] + colonIndex],
545+
}),
546+
name: this.createNode<TSESTree.JSXIdentifier>(node, {
547+
type: AST_NODE_TYPES.JSXIdentifier,
548+
name: text.slice(colonIndex + 1),
549+
range: [range[0] + colonIndex + 1, range[1]],
550+
}),
551+
range,
552+
});
553+
this.registerTSNodeInNodeMap(node, result);
554+
return result;
555+
}
556+
557+
return this.convertJSXIdentifier(node);
558+
}
559+
520560
/**
521561
* Converts a TypeScript JSX node.tagName into an ESTree node.name
522562
* @param node the tagName object from a JSX ts.Node
@@ -526,8 +566,8 @@ export class Converter {
526566
private convertJSXTagName(
527567
node: ts.JsxTagNameExpression,
528568
parent: ts.Node,
529-
): TSESTree.JSXMemberExpression | TSESTree.JSXIdentifier {
530-
let result: TSESTree.JSXMemberExpression | TSESTree.JSXIdentifier;
569+
): TSESTree.JSXTagNameExpression {
570+
let result: TSESTree.JSXTagNameExpression;
531571
switch (node.kind) {
532572
case SyntaxKind.PropertyAccessExpression:
533573
if (node.name.kind === SyntaxKind.PrivateIdentifier) {
@@ -539,27 +579,14 @@ export class Converter {
539579
result = this.createNode<TSESTree.JSXMemberExpression>(node, {
540580
type: AST_NODE_TYPES.JSXMemberExpression,
541581
object: this.convertJSXTagName(node.expression, parent),
542-
property: this.convertJSXTagName(
543-
node.name,
544-
parent,
545-
) as TSESTree.JSXIdentifier,
582+
property: this.convertJSXIdentifier(node.name),
546583
});
547584
break;
548585

549586
case SyntaxKind.ThisKeyword:
550-
result = this.createNode<TSESTree.JSXIdentifier>(node, {
551-
type: AST_NODE_TYPES.JSXIdentifier,
552-
name: 'this',
553-
});
554-
break;
555-
556587
case SyntaxKind.Identifier:
557588
default:
558-
result = this.createNode<TSESTree.JSXIdentifier>(node, {
559-
type: AST_NODE_TYPES.JSXIdentifier,
560-
name: node.text,
561-
});
562-
break;
589+
return this.convertJSXNamespaceOrIdentifier(node);
563590
}
564591

565592
this.registerTSNodeInNodeMap(node, result);
@@ -2113,12 +2140,9 @@ export class Converter {
21132140
}
21142141

21152142
case SyntaxKind.JsxAttribute: {
2116-
const attributeName = this.convertChild(node.name);
2117-
attributeName.type = AST_NODE_TYPES.JSXIdentifier;
2118-
21192143
return this.createNode<TSESTree.JSXAttribute>(node, {
21202144
type: AST_NODE_TYPES.JSXAttribute,
2121-
name: attributeName,
2145+
name: this.convertJSXNamespaceOrIdentifier(node.name),
21222146
value: this.convertChild(node.initializer),
21232147
});
21242148
}
@@ -2407,36 +2431,40 @@ export class Converter {
24072431
}
24082432
return result;
24092433
}
2410-
case SyntaxKind.ConstructorType:
2434+
case SyntaxKind.ConstructorType: {
2435+
const result = this.createNode<TSESTree.TSConstructorType>(node, {
2436+
type: AST_NODE_TYPES.TSConstructorType,
2437+
params: this.convertParameters(node.parameters),
2438+
abstract: hasModifier(SyntaxKind.AbstractKeyword, node),
2439+
});
2440+
if (node.type) {
2441+
result.returnType = this.convertTypeAnnotation(node.type, node);
2442+
}
2443+
if (node.typeParameters) {
2444+
result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(
2445+
node.typeParameters,
2446+
);
2447+
}
2448+
return result;
2449+
}
2450+
24112451
case SyntaxKind.FunctionType:
24122452
case SyntaxKind.ConstructSignature:
24132453
case SyntaxKind.CallSignature: {
2414-
let type: AST_NODE_TYPES;
2415-
switch (node.kind) {
2416-
case SyntaxKind.ConstructSignature:
2417-
type = AST_NODE_TYPES.TSConstructSignatureDeclaration;
2418-
break;
2419-
case SyntaxKind.CallSignature:
2420-
type = AST_NODE_TYPES.TSCallSignatureDeclaration;
2421-
break;
2422-
case SyntaxKind.FunctionType:
2423-
type = AST_NODE_TYPES.TSFunctionType;
2424-
break;
2425-
case SyntaxKind.ConstructorType:
2426-
default:
2427-
type = AST_NODE_TYPES.TSConstructorType;
2428-
break;
2429-
}
2454+
const type =
2455+
node.kind === SyntaxKind.ConstructSignature
2456+
? AST_NODE_TYPES.TSConstructSignatureDeclaration
2457+
: node.kind === SyntaxKind.CallSignature
2458+
? AST_NODE_TYPES.TSCallSignatureDeclaration
2459+
: AST_NODE_TYPES.TSFunctionType;
24302460
const result = this.createNode<
2431-
| TSESTree.TSConstructSignatureDeclaration
2432-
| TSESTree.TSCallSignatureDeclaration
24332461
| TSESTree.TSFunctionType
2434-
| TSESTree.TSConstructorType
2462+
| TSESTree.TSCallSignatureDeclaration
2463+
| TSESTree.TSConstructSignatureDeclaration
24352464
>(node, {
24362465
type: type,
24372466
params: this.convertParameters(node.parameters),
24382467
});
2439-
24402468
if (node.type) {
24412469
result.returnType = this.convertTypeAnnotation(node.type, node);
24422470
}
@@ -2446,7 +2474,6 @@ export class Converter {
24462474
node.typeParameters,
24472475
);
24482476
}
2449-
24502477
return result;
24512478
}
24522479

@@ -2694,7 +2721,7 @@ export class Converter {
26942721
? (node as any).elementTypes.map((el: ts.Node) =>
26952722
this.convertType(el),
26962723
)
2697-
: node.elements.map((el: ts.Node) => this.convertType(el));
2724+
: node.elements.map(el => this.convertType(el));
26982725

26992726
return this.createNode<TSESTree.TSTupleType>(node, {
27002727
type: AST_NODE_TYPES.TSTupleType,

packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export interface EstreeToTsNodeTypes {
9393
[AST_NODE_TYPES.JSXSpreadAttribute]: ts.JsxSpreadAttribute;
9494
[AST_NODE_TYPES.JSXSpreadChild]: ts.JsxExpression;
9595
[AST_NODE_TYPES.JSXMemberExpression]: ts.PropertyAccessExpression;
96+
[AST_NODE_TYPES.JSXNamespacedName]: ts.Identifier | ts.ThisExpression;
9697
[AST_NODE_TYPES.JSXText]: ts.JsxText;
9798
[AST_NODE_TYPES.LabeledStatement]: ts.LabeledStatement;
9899
[AST_NODE_TYPES.Literal]:
@@ -157,15 +158,11 @@ export interface EstreeToTsNodeTypes {
157158
| ts.ConstructorDeclaration;
158159
[AST_NODE_TYPES.TSArrayType]: ts.ArrayTypeNode;
159160
[AST_NODE_TYPES.TSAsExpression]: ts.AsExpression;
160-
[AST_NODE_TYPES.TSCallSignatureDeclaration]: ts.PropertySignature;
161+
[AST_NODE_TYPES.TSCallSignatureDeclaration]: ts.CallSignatureDeclaration;
161162
[AST_NODE_TYPES.TSClassImplements]: ts.ExpressionWithTypeArguments;
162163
[AST_NODE_TYPES.TSConditionalType]: ts.ConditionalTypeNode;
163164
[AST_NODE_TYPES.TSConstructorType]: ts.ConstructorTypeNode;
164-
[AST_NODE_TYPES.TSConstructSignatureDeclaration]:
165-
| ts.ConstructorTypeNode
166-
| ts.FunctionTypeNode
167-
| ts.ConstructSignatureDeclaration
168-
| ts.CallSignatureDeclaration;
165+
[AST_NODE_TYPES.TSConstructSignatureDeclaration]: ts.ConstructSignatureDeclaration;
169166
[AST_NODE_TYPES.TSDeclareFunction]: ts.FunctionDeclaration;
170167
[AST_NODE_TYPES.TSEnumDeclaration]: ts.EnumDeclaration;
171168
[AST_NODE_TYPES.TSEnumMember]: ts.EnumMember;

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -299,23 +299,19 @@ tester.addFixturePatternConfig('jsx', {
299299
* https://github.com/Microsoft/TypeScript/issues/7410
300300
*/
301301
'embedded-tags',
302-
/**
303-
* JSX fixtures which have known issues for typescript-estree
304-
* @see https://github.com/Microsoft/TypeScript/issues/7411
305-
*/
306-
'namespaced-attribute-and-value-inserted',
307-
/**
308-
* JSX fixtures which have known issues for typescript-estree
309-
* @see https://github.com/Microsoft/TypeScript/issues/7411
310-
*/
311-
'namespaced-name-and-attribute',
312302
/**
313303
* Current random error difference on jsx/invalid-no-tag-name.src.js
314304
* ts-estree - SyntaxError
315305
* Babel - RangeError
316306
* @see https://github.com/babel/babel/issues/6680
317307
*/
318308
'invalid-no-tag-name',
309+
/**
310+
* [BABEL ERRORED, BUT TS-ESTREE DID NOT]
311+
* SyntaxError: Unexpected token
312+
* TODO: investigate if this code is valid as there is no typescript error
313+
*/
314+
'invalid-namespace-value-with-dots',
319315
],
320316
});
321317
tester.addFixturePatternConfig('jsx-useJSXTextNode');
@@ -346,7 +342,7 @@ tester.addFixturePatternConfig('typescript/basics', {
346342
/**
347343
* Babel parses it as TSQualifiedName
348344
* ts parses it as MemberExpression
349-
* TODO: report it to babel
345+
* @see https://github.com/babel/babel/issues/12884
350346
*/
351347
'interface-with-extends-member-expression',
352348
/**
@@ -387,7 +383,7 @@ tester.addFixturePatternConfig('typescript/basics', {
387383
'import-type-error',
388384
/**
389385
* [TS-ESTREE ERRORED, BUT BABEL DID NOT]
390-
* TODO: report this to babel
386+
* This is intentional; babel is not checking types
391387
*/
392388
'catch-clause-with-invalid-annotation',
393389
],

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