{
"body": [
{
"expression": {
"arguments": [],
"callee": {
"expression": {
"expression": {
"computed": false,
"loc": {
"end": { "column": 5, "line": 1 },
"start": { "column": 1, "line": 1 }
},
"object": {
"loc": {
"end": { "column": 2, "line": 1 },
"start": { "column": 1, "line": 1 }
},
"name": "a",
"range": [1, 2],
"type": "Identifier"
},
"optional": true,
"property": {
"loc": {
"end": { "column": 5, "line": 1 },
"start": { "column": 4, "line": 1 }
},
"name": "b",
"range": [4, 5],
"type": "Identifier"
},
"range": [1, 5],
"type": "MemberExpression"
},
"loc": {
"end": { "column": 5, "line": 1 },
"start": { "column": 1, "line": 1 }
},
"range": [1, 5],
"type": "ChainExpression"
},
"loc": {
"end": { "column": 8, "line": 1 },
"start": { "column": 1, "line": 1 }
},
"range": [1, 8],
"type": "TSInstantiationExpression",
"typeParameters": {
"loc": {
"end": { "column": 8, "line": 1 },
"start": { "column": 5, "line": 1 }
},
"params": [
{
"loc": {
"end": { "column": 7, "line": 1 },
"start": { "column": 6, "line": 1 }
},
"range": [6, 7],
"type": "TSTypeReference",
"typeName": {
"loc": {
"end": { "column": 7, "line": 1 },
"start": { "column": 6, "line": 1 }
},
"name": "c",
"range": [6, 7],
"type": "Identifier"
}
}
],
"range": [5, 8],
"type": "TSTypeParameterInstantiation"
}
},
"loc": {
"end": { "column": 14, "line": 1 },
"start": { "column": 0, "line": 1 }
},
"optional": false,
"range": [0, 14],
"type": "CallExpression",
"typeParameters": {
"loc": {
"end": { "column": 12, "line": 1 },
"start": { "column": 9, "line": 1 }
},
"params": [
{
"loc": {
"end": { "column": 11, "line": 1 },
"start": { "column": 10, "line": 1 }
},
"range": [10, 11],
"type": "TSTypeReference",
"typeName": {
"loc": {
"end": { "column": 11, "line": 1 },
"start": { "column": 10, "line": 1 }
},
"name": "d",
"range": [10, 11],
"type": "Identifier"
}
}
],
"range": [9, 12],
"type": "TSTypeParameterInstantiation"
}
},
"loc": {
"end": { "column": 15, "line": 1 },
"start": { "column": 0, "line": 1 }
},
"range": [0, 15],
"type": "ExpressionStatement"
}
],
"sourceType": "script",
"type": "Program"
}
💻
How are you using Babel?
Programmatic API (
babel.transform,babel.parse)Input code
incorrectly generated ast:
correctly generated ast
full test sample:
Configuration file name
No response
Configuration
Current and expected behavior
TSInstantiationExpression should define typeParameters and structure should be different
expected:
TSInstantiationExpression > { typeParameters: *, expression: ChainExpression }
received:
ChainExpression > { typeParameters: *, expression: TSInstantiationExpression }
From what I can tell issue is present only if optional chain expression is used,
?ina?.b<c>;looks like issue is present only when converting nodes to estree (to be verified)
Expected AST
{ "body": [ { "expression": { "arguments": [], "callee": { "expression": { "expression": { "computed": false, "loc": { "end": { "column": 5, "line": 1 }, "start": { "column": 1, "line": 1 } }, "object": { "loc": { "end": { "column": 2, "line": 1 }, "start": { "column": 1, "line": 1 } }, "name": "a", "range": [1, 2], "type": "Identifier" }, "optional": true, "property": { "loc": { "end": { "column": 5, "line": 1 }, "start": { "column": 4, "line": 1 } }, "name": "b", "range": [4, 5], "type": "Identifier" }, "range": [1, 5], "type": "MemberExpression" }, "loc": { "end": { "column": 5, "line": 1 }, "start": { "column": 1, "line": 1 } }, "range": [1, 5], "type": "ChainExpression" }, "loc": { "end": { "column": 8, "line": 1 }, "start": { "column": 1, "line": 1 } }, "range": [1, 8], "type": "TSInstantiationExpression", "typeParameters": { "loc": { "end": { "column": 8, "line": 1 }, "start": { "column": 5, "line": 1 } }, "params": [ { "loc": { "end": { "column": 7, "line": 1 }, "start": { "column": 6, "line": 1 } }, "range": [6, 7], "type": "TSTypeReference", "typeName": { "loc": { "end": { "column": 7, "line": 1 }, "start": { "column": 6, "line": 1 } }, "name": "c", "range": [6, 7], "type": "Identifier" } } ], "range": [5, 8], "type": "TSTypeParameterInstantiation" } }, "loc": { "end": { "column": 14, "line": 1 }, "start": { "column": 0, "line": 1 } }, "optional": false, "range": [0, 14], "type": "CallExpression", "typeParameters": { "loc": { "end": { "column": 12, "line": 1 }, "start": { "column": 9, "line": 1 } }, "params": [ { "loc": { "end": { "column": 11, "line": 1 }, "start": { "column": 10, "line": 1 } }, "range": [10, 11], "type": "TSTypeReference", "typeName": { "loc": { "end": { "column": 11, "line": 1 }, "start": { "column": 10, "line": 1 } }, "name": "d", "range": [10, 11], "type": "Identifier" } } ], "range": [9, 12], "type": "TSTypeParameterInstantiation" } }, "loc": { "end": { "column": 15, "line": 1 }, "start": { "column": 0, "line": 1 } }, "range": [0, 15], "type": "ExpressionStatement" } ], "sourceType": "script", "type": "Program" }Received AST
{ "body": [ { "expression": { "arguments": [], "callee": { "expression": { "expression": { "computed": false, "loc": { "end": { "column": 5, "line": 1 }, "start": { "column": 1, "line": 1 } }, "object": { "loc": { "end": { "column": 2, "line": 1 }, "start": { "column": 1, "line": 1 } }, "name": "a", "range": [1, 2], "type": "Identifier" }, "optional": true, "property": { "loc": { "end": { "column": 5, "line": 1 }, "start": { "column": 4, "line": 1 } }, "name": "b", "range": [4, 5], "type": "Identifier" }, "range": [1, 5], "type": "MemberExpression" }, "loc": { "end": { "column": 8, "line": 1 }, "start": { "column": 1, "line": 1 } }, "range": [1, 8], "type": "TSInstantiationExpression", "typeParameters": { "loc": { "end": { "column": 8, "line": 1 }, "start": { "column": 5, "line": 1 } }, "params": [ { "loc": { "end": { "column": 7, "line": 1 }, "start": { "column": 6, "line": 1 } }, "range": [6, 7], "type": "TSTypeReference", "typeName": { "loc": { "end": { "column": 7, "line": 1 }, "start": { "column": 6, "line": 1 } }, "name": "c", "range": [6, 7], "type": "Identifier" } } ], "range": [5, 8], "type": "TSTypeParameterInstantiation" } }, "loc": { "end": { "column": 8, "line": 1 }, "start": { "column": 1, "line": 1 } }, "range": [1, 8], "type": "ChainExpression" }, "loc": { "end": { "column": 14, "line": 1 }, "start": { "column": 0, "line": 1 } }, "optional": false, "range": [0, 14], "type": "CallExpression", "typeParameters": { "loc": { "end": { "column": 12, "line": 1 }, "start": { "column": 9, "line": 1 } }, "params": [ { "loc": { "end": { "column": 11, "line": 1 }, "start": { "column": 10, "line": 1 } }, "range": [10, 11], "type": "TSTypeReference", "typeName": { "loc": { "end": { "column": 11, "line": 1 }, "start": { "column": 10, "line": 1 } }, "name": "d", "range": [10, 11], "type": "Identifier" } } ], "range": [9, 12], "type": "TSTypeParameterInstantiation" } }, "loc": { "end": { "column": 15, "line": 1 }, "start": { "column": 0, "line": 1 } }, "range": [0, 15], "type": "ExpressionStatement" } ], "sourceType": "script", "type": "Program" }astexplorer has to old version of babel to show it, but you can see expected result for ts-eslint
typescript-eslint.io/play
Environment
^7.18.2Additional context
I'm not fully confident that ts-estree produce fully correct structure here but
typeParametersshould be located onTSInstantiationExpressioninstead ofChainExpressionhttps://github.com/typescript-eslint/typescript-eslint/blob/c4310b1aac35c7d31b826f0602eca6a5900a09ee/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts#L457-L461
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/shared-fixtures/fixtures/typescript/expressions/instantiation-expression.src.ts