diff --git a/.prettierignore b/.prettierignore index 048e552b38b..ac7951991af 100644 --- a/.prettierignore +++ b/.prettierignore @@ -15,3 +15,7 @@ CONTRIBUTORS.md # Ignore CHANGELOG.md files to avoid issues with automated release job CHANGELOG.md + +# TODO - remove this once prettier supports labelled tuples +packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts +packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts diff --git a/packages/eslint-plugin/src/rules/no-unused-vars-experimental.ts b/packages/eslint-plugin/src/rules/no-unused-vars-experimental.ts index c8586973861..ad7c3f41742 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars-experimental.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars-experimental.ts @@ -140,7 +140,6 @@ export default util.createRule({ case ts.SyntaxKind.ImportSpecifier: // a namespace import is NOT used, but the default import is used case ts.SyntaxKind.NamespaceImport: - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum report('Import'); break; diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars-experimental.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars-experimental.test.ts index 19e36292f03..c093498200c 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars-experimental.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars-experimental.test.ts @@ -972,7 +972,6 @@ export function foo([[a]], used) { messageId: 'unusedWithIgnorePattern', data: { name: 'foo', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, @@ -1047,7 +1046,6 @@ console.log(named); messageId: 'unusedWithIgnorePattern', data: { name: 'defaultImp', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, @@ -1067,7 +1065,6 @@ console.log(named); messageId: 'unusedWithIgnorePattern', data: { name: 'defaultImp', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, @@ -1087,7 +1084,6 @@ console.log(defaultImp); messageId: 'unusedWithIgnorePattern', data: { name: 'named', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, @@ -1107,7 +1103,6 @@ console.log(defaultImp); messageId: 'unusedWithIgnorePattern', data: { name: 'named', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, @@ -1127,7 +1122,6 @@ console.log(named1); messageId: 'unusedWithIgnorePattern', data: { name: 'named2', - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum type: 'Import', pattern: DEFAULT_IGNORED_REGEX, }, diff --git a/packages/parser/tests/lib/__snapshots__/typescript.ts.snap b/packages/parser/tests/lib/__snapshots__/typescript.ts.snap index 8fb911f4d4a..82c3f822c80 100644 --- a/packages/parser/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/parser/tests/lib/__snapshots__/typescript.ts.snap @@ -20934,7 +20934,7 @@ Object { }, "node": Object { "range": Array [ - 7, + 12, 15, ], "type": "ImportDefaultSpecifier", @@ -21139,7 +21139,7 @@ Object { }, "node": Object { "range": Array [ - 7, + 12, 15, ], "type": "ImportDefaultSpecifier", @@ -53389,6 +53389,359 @@ Object { } `; +exports[`typescript fixtures/types/tuple-named.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 42, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 42, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object { + "x": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "x", + "range": Array [ + 4, + 40, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 4, + 40, + ], + "type": "VariableDeclarator", + }, + "parent": Object { + "range": Array [ + 0, + 41, + ], + "type": "VariableDeclaration", + }, + "type": "Variable", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "x", + "range": Array [ + 4, + 40, + ], + "type": "Identifier", + }, + ], + "name": "x", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/types/tuple-named-optional.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 54, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 54, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object { + "x": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "x", + "range": Array [ + 4, + 53, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 4, + 53, + ], + "type": "VariableDeclarator", + }, + "parent": Object { + "range": Array [ + 0, + 53, + ], + "type": "VariableDeclaration", + }, + "type": "Variable", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "x", + "range": Array [ + 4, + 53, + ], + "type": "Identifier", + }, + ], + "name": "x", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/types/tuple-named-rest.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object { + "x": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "x", + "range": Array [ + 4, + 34, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 4, + 34, + ], + "type": "VariableDeclarator", + }, + "parent": Object { + "range": Array [ + 0, + 34, + ], + "type": "VariableDeclaration", + }, + "type": "Variable", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "x", + "range": Array [ + 4, + 34, + ], + "type": "Identifier", + }, + ], + "name": "x", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/types/tuple-named-type.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + exports[`typescript fixtures/types/tuple-optional.src 1`] = ` Object { "$id": 2, diff --git a/packages/scope-manager/src/referencer/TypeVisitor.ts b/packages/scope-manager/src/referencer/TypeVisitor.ts index f4f895279f0..49f0ac12743 100644 --- a/packages/scope-manager/src/referencer/TypeVisitor.ts +++ b/packages/scope-manager/src/referencer/TypeVisitor.ts @@ -145,6 +145,11 @@ class TypeVisitor extends Visitor { this.visitFunctionType(node); } + protected TSNamedTupleMember(node: TSESTree.TSNamedTupleMember): void { + this.visit(node.elementType); + // we don't visit the label as the label only exists for the purposes of documentation + } + protected TSPropertySignature(node: TSESTree.TSPropertySignature): void { this.visitPropertyKey(node); this.visit(node.typeAnnotation); diff --git a/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts new file mode 100644 index 00000000000..97cade48b9b --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts @@ -0,0 +1,2 @@ +type T = 1; +type A = [...a: T[]]; diff --git a/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts.shot b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts.shot new file mode 100644 index 00000000000..6a0b9edd562 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled-rest.ts.shot @@ -0,0 +1,58 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`type-declaration tuple-labelled-rest 1`] = ` +ScopeManager { + variables: Array [ + Variable$1 { + defs: Array [ + TypeDefinition$1 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$1, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + isTypeReference: true, + isValueReference: false, + resolved: Variable$1, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$2 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"A">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "A", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [ + Reference$1, + ], + set: Map { + "T" => Variable$1, + "A" => Variable$2, + }, + type: "global", + upper: null, + variables: Array [ + Variable$1, + Variable$2, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts new file mode 100644 index 00000000000..8314282aeca --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts @@ -0,0 +1,3 @@ +type T1 = 1; +type T2 = 2; +type A = [a: T1, b?: T2]; diff --git a/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts.shot b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts.shot new file mode 100644 index 00000000000..5a68bbab205 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/tuple-labelled.ts.shot @@ -0,0 +1,80 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`type-declaration tuple-labelled 1`] = ` +ScopeManager { + variables: Array [ + Variable$1 { + defs: Array [ + TypeDefinition$1 { + name: Identifier<"T1">, + node: TSTypeAliasDeclaration$1, + }, + ], + name: "T1", + references: Array [ + Reference$1 { + identifier: Identifier<"T1">, + isTypeReference: true, + isValueReference: false, + resolved: Variable$1, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$2 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"T2">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "T2", + references: Array [ + Reference$2 { + identifier: Identifier<"T2">, + isTypeReference: true, + isValueReference: false, + resolved: Variable$2, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + TypeDefinition$3 { + name: Identifier<"A">, + node: TSTypeAliasDeclaration$3, + }, + ], + name: "A", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$4, + isStrict: false, + references: Array [ + Reference$1, + Reference$2, + ], + set: Map { + "T1" => Variable$1, + "T2" => Variable$2, + "A" => Variable$3, + }, + type: "global", + upper: null, + variables: Array [ + Variable$1, + Variable$2, + Variable$3, + ], + }, + ], +} +`; diff --git a/packages/shared-fixtures/fixtures/typescript/types/tuple-named-optional.src.ts b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-optional.src.ts new file mode 100644 index 00000000000..6704f9b6f11 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-optional.src.ts @@ -0,0 +1 @@ +let x: [a: string, b?: number, c?: (string | number)] diff --git a/packages/shared-fixtures/fixtures/typescript/types/tuple-named-rest.src.ts b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-rest.src.ts new file mode 100644 index 00000000000..5320dd800c7 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-rest.src.ts @@ -0,0 +1 @@ +let x: [a: string, ...b: number[]] diff --git a/packages/shared-fixtures/fixtures/typescript/types/tuple-named-type.src.ts b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-type.src.ts new file mode 100644 index 00000000000..d0d24cf3b95 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/types/tuple-named-type.src.ts @@ -0,0 +1 @@ +type Foo = [a: string, b?: string] diff --git a/packages/shared-fixtures/fixtures/typescript/types/tuple-named.src.ts b/packages/shared-fixtures/fixtures/typescript/types/tuple-named.src.ts new file mode 100644 index 00000000000..a714c8ab33e --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/types/tuple-named.src.ts @@ -0,0 +1 @@ +let x: [a: number, b: number, c: number]; diff --git a/packages/types/src/ast-node-types.ts b/packages/types/src/ast-node-types.ts index cbf72617453..29f5b0bfe51 100644 --- a/packages/types/src/ast-node-types.ts +++ b/packages/types/src/ast-node-types.ts @@ -32,7 +32,6 @@ enum AST_NODE_TYPES { FunctionExpression = 'FunctionExpression', Identifier = 'Identifier', IfStatement = 'IfStatement', - Import = 'Import', ImportDeclaration = 'ImportDeclaration', ImportDefaultSpecifier = 'ImportDefaultSpecifier', ImportExpression = 'ImportExpression', @@ -95,42 +94,46 @@ enum AST_NODE_TYPES { TSArrayType = 'TSArrayType', TSAsExpression = 'TSAsExpression', TSAsyncKeyword = 'TSAsyncKeyword', - TSBooleanKeyword = 'TSBooleanKeyword', TSBigIntKeyword = 'TSBigIntKeyword', - TSConditionalType = 'TSConditionalType', - TSConstructorType = 'TSConstructorType', + TSBooleanKeyword = 'TSBooleanKeyword', TSCallSignatureDeclaration = 'TSCallSignatureDeclaration', TSClassImplements = 'TSClassImplements', + TSConditionalType = 'TSConditionalType', + TSConstructorType = 'TSConstructorType', TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration', - TSDeclareKeyword = 'TSDeclareKeyword', TSDeclareFunction = 'TSDeclareFunction', + TSDeclareKeyword = 'TSDeclareKeyword', TSEmptyBodyFunctionExpression = 'TSEmptyBodyFunctionExpression', TSEnumDeclaration = 'TSEnumDeclaration', TSEnumMember = 'TSEnumMember', TSExportAssignment = 'TSExportAssignment', TSExportKeyword = 'TSExportKeyword', TSExternalModuleReference = 'TSExternalModuleReference', + TSFunctionType = 'TSFunctionType', + TSImportEqualsDeclaration = 'TSImportEqualsDeclaration', TSImportType = 'TSImportType', - TSInferType = 'TSInferType', - TSLiteralType = 'TSLiteralType', TSIndexedAccessType = 'TSIndexedAccessType', TSIndexSignature = 'TSIndexSignature', + TSInferType = 'TSInferType', TSInterfaceBody = 'TSInterfaceBody', TSInterfaceDeclaration = 'TSInterfaceDeclaration', TSInterfaceHeritage = 'TSInterfaceHeritage', - TSImportEqualsDeclaration = 'TSImportEqualsDeclaration', - TSFunctionType = 'TSFunctionType', + TSIntersectionType = 'TSIntersectionType', + TSLiteralType = 'TSLiteralType', + TSMappedType = 'TSMappedType', TSMethodSignature = 'TSMethodSignature', TSModuleBlock = 'TSModuleBlock', TSModuleDeclaration = 'TSModuleDeclaration', + TSNamedTupleMember = 'TSNamedTupleMember', TSNamespaceExportDeclaration = 'TSNamespaceExportDeclaration', - TSNonNullExpression = 'TSNonNullExpression', TSNeverKeyword = 'TSNeverKeyword', + TSNonNullExpression = 'TSNonNullExpression', TSNullKeyword = 'TSNullKeyword', TSNumberKeyword = 'TSNumberKeyword', - TSMappedType = 'TSMappedType', TSObjectKeyword = 'TSObjectKeyword', + TSOptionalType = 'TSOptionalType', TSParameterProperty = 'TSParameterProperty', + TSParenthesizedType = 'TSParenthesizedType', TSPrivateKeyword = 'TSPrivateKeyword', TSPropertySignature = 'TSPropertySignature', TSProtectedKeyword = 'TSProtectedKeyword', @@ -142,8 +145,9 @@ enum AST_NODE_TYPES { TSStringKeyword = 'TSStringKeyword', TSSymbolKeyword = 'TSSymbolKeyword', TSThisType = 'TSThisType', - TSTypeAnnotation = 'TSTypeAnnotation', + TSTupleType = 'TSTupleType', TSTypeAliasDeclaration = 'TSTypeAliasDeclaration', + TSTypeAnnotation = 'TSTypeAnnotation', TSTypeAssertion = 'TSTypeAssertion', TSTypeLiteral = 'TSTypeLiteral', TSTypeOperator = 'TSTypeOperator', @@ -151,16 +155,27 @@ enum AST_NODE_TYPES { TSTypeParameterDeclaration = 'TSTypeParameterDeclaration', TSTypeParameterInstantiation = 'TSTypeParameterInstantiation', TSTypePredicate = 'TSTypePredicate', - TSTypeReference = 'TSTypeReference', TSTypeQuery = 'TSTypeQuery', - TSIntersectionType = 'TSIntersectionType', - TSTupleType = 'TSTupleType', - TSOptionalType = 'TSOptionalType', - TSParenthesizedType = 'TSParenthesizedType', - TSUnionType = 'TSUnionType', + TSTypeReference = 'TSTypeReference', TSUndefinedKeyword = 'TSUndefinedKeyword', + TSUnionType = 'TSUnionType', TSUnknownKeyword = 'TSUnknownKeyword', TSVoidKeyword = 'TSVoidKeyword', } export { AST_NODE_TYPES }; + +// Below is a special type-only test which ensures that we don't accidentally leave unused keys in this enum +// eslint-disable-next-line import/first -- purposely down here to colocate it with this hack of a test +import type { Node } from './ts-estree'; + +type GetKeys = keyof Extract; +type AllKeys = { + readonly [T in AST_NODE_TYPES]: GetKeys; +}; +type TakesString> = T; +// @ts-expect-error: purposely unused +type _Test = + // forcing the test onto a new line so it isn't covered by the expect error + // If there are any enum members that don't have a corresponding TSESTree.Node, then this line will error with "Type 'string | number | symbol' is not assignable to type 'string'." + void | TakesString; diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 527e67623f1..ea6e1dfea1c 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -186,11 +186,11 @@ export type Node = | JSXExpressionContainer | JSXFragment | JSXIdentifier + | JSXMemberExpression | JSXOpeningElement | JSXOpeningFragment | JSXSpreadAttribute | JSXSpreadChild - | JSXMemberExpression | JSXText | LabeledStatement | Literal @@ -246,8 +246,8 @@ export type Node = | TSIndexedAccessType | TSIndexSignature | TSInferType - | TSInterfaceDeclaration | TSInterfaceBody + | TSInterfaceDeclaration | TSInterfaceHeritage | TSIntersectionType | TSLiteralType @@ -255,6 +255,7 @@ export type Node = | TSMethodSignature | TSModuleBlock | TSModuleDeclaration + | TSNamedTupleMember | TSNamespaceExportDeclaration | TSNeverKeyword | TSNonNullExpression @@ -264,10 +265,10 @@ export type Node = | TSOptionalType | TSParameterProperty | TSParenthesizedType - | TSPropertySignature - | TSPublicKeyword | TSPrivateKeyword + | TSPropertySignature | TSProtectedKeyword + | TSPublicKeyword | TSQualifiedName | TSReadonlyKeyword | TSRestType @@ -291,8 +292,8 @@ export type Node = | TSUnionType | TSUnknownKeyword | TSVoidKeyword - | UpdateExpression | UnaryExpression + | UpdateExpression | VariableDeclaration | VariableDeclarator | WhileStatement @@ -525,6 +526,7 @@ export type TypeNode = | TSIntersectionType | TSLiteralType | TSMappedType + | TSNamedTupleMember | TSNeverKeyword | TSNullKeyword | TSNumberKeyword @@ -539,8 +541,8 @@ export type TypeNode = | TSTypeLiteral | TSTypeOperator | TSTypePredicate - | TSTypeReference | TSTypeQuery + | TSTypeReference | TSUndefinedKeyword | TSUnionType | TSUnknownKeyword @@ -1603,6 +1605,13 @@ export interface TSThisType extends BaseNode { type: AST_NODE_TYPES.TSThisType; } +export interface TSNamedTupleMember extends BaseNode { + type: AST_NODE_TYPES.TSNamedTupleMember; + elementType: TypeNode; + label: Identifier; + optional: boolean; +} + export interface TSTupleType extends BaseNode { type: AST_NODE_TYPES.TSTupleType; elementTypes: TypeNode[]; diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 28a04f2ba2a..d3549615a9e 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -50,9 +50,9 @@ "tsutils": "^3.17.1" }, "devDependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.11.3", + "@babel/types": "^7.11.0", "@types/babel__code-frame": "^7.0.1", "@types/debug": "^4.1.5", "@types/is-glob": "^4.0.1", diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 7a137c3335f..69ba262fa30 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -1603,12 +1603,14 @@ export class Converter { imported: this.convertChild(node.propertyName ?? node.name), }); - case SyntaxKind.ImportClause: + case SyntaxKind.ImportClause: { + const local = this.convertChild(node.name); return this.createNode(node, { type: AST_NODE_TYPES.ImportDefaultSpecifier, - local: this.convertChild(node.name), - range: [node.getStart(this.ast), node.name!.end], + local, + range: local.range, }); + } case SyntaxKind.ExportDeclaration: if (node.exportClause?.kind === SyntaxKind.NamedExports) { @@ -2621,34 +2623,12 @@ export class Converter { } // TypeScript specific types - case SyntaxKind.OptionalType: { - return this.createNode(node, { - type: AST_NODE_TYPES.TSOptionalType, - typeAnnotation: this.convertType(node.type), - }); - } case SyntaxKind.ParenthesizedType: { return this.createNode(node, { type: AST_NODE_TYPES.TSParenthesizedType, typeAnnotation: this.convertType(node.type), }); } - case SyntaxKind.TupleType: { - // In TS 4.0, the `elementTypes` property was changed to `elements`. - // To support both at compile time, we cast to access the newer version - // if the former does not exist. - const elementTypes = - 'elementTypes' in node - ? (node as any).elementTypes.map((el: ts.Node) => - this.convertType(el), - ) - : node.elements.map((el: ts.Node) => this.convertType(el)); - - return this.createNode(node, { - type: AST_NODE_TYPES.TSTupleType, - elementTypes, - }); - } case SyntaxKind.UnionType: { return this.createNode(node, { type: AST_NODE_TYPES.TSUnionType, @@ -2661,12 +2641,6 @@ export class Converter { types: node.types.map(el => this.convertType(el)), }); } - case SyntaxKind.RestType: { - return this.createNode(node, { - type: AST_NODE_TYPES.TSRestType, - typeAnnotation: this.convertType(node.type), - }); - } case SyntaxKind.AsExpression: { return this.createNode(node, { type: AST_NODE_TYPES.TSAsExpression, @@ -2732,6 +2706,57 @@ export class Converter { type: AST_NODE_TYPES.TSAbstractKeyword, }); } + + // Tuple + case SyntaxKind.TupleType: { + // In TS 4.0, the `elementTypes` property was changed to `elements`. + // To support both at compile time, we cast to access the newer version + // if the former does not exist. + const elementTypes = + 'elementTypes' in node + ? (node as any).elementTypes.map((el: ts.Node) => + this.convertType(el), + ) + : node.elements.map((el: ts.Node) => this.convertType(el)); + + return this.createNode(node, { + type: AST_NODE_TYPES.TSTupleType, + elementTypes, + }); + } + case SyntaxKind.NamedTupleMember: { + const member = this.createNode(node, { + type: AST_NODE_TYPES.TSNamedTupleMember, + elementType: this.convertType(node.type, node), + label: this.convertChild(node.name, node), + optional: node.questionToken != null, + }); + + if (node.dotDotDotToken) { + // adjust the start to account for the "..." + member.range[0] = member.label.range[0]; + member.loc.start = member.label.loc.start; + return this.createNode(node, { + type: AST_NODE_TYPES.TSRestType, + typeAnnotation: member, + }); + } + + return member; + } + case SyntaxKind.OptionalType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSOptionalType, + typeAnnotation: this.convertType(node.type), + }); + } + case SyntaxKind.RestType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSRestType, + typeAnnotation: this.convertType(node.type), + }); + } + default: return this.deeplyCopy(node); } diff --git a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts index 4d201d49c97..7816ea3d0ca 100644 --- a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts +++ b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts @@ -68,7 +68,6 @@ export interface EstreeToTsNodeTypes { | ts.ConstructorDeclaration | ts.Token; [AST_NODE_TYPES.IfStatement]: ts.IfStatement; - [AST_NODE_TYPES.Import]: ts.ImportExpression; [AST_NODE_TYPES.ImportDeclaration]: ts.ImportDeclaration; [AST_NODE_TYPES.ImportDefaultSpecifier]: ts.ImportClause; [AST_NODE_TYPES.ImportExpression]: ts.CallExpression; @@ -186,6 +185,7 @@ export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.TSMethodSignature]: ts.MethodSignature; [AST_NODE_TYPES.TSModuleBlock]: ts.ModuleBlock; [AST_NODE_TYPES.TSModuleDeclaration]: ts.ModuleDeclaration; + [AST_NODE_TYPES.TSNamedTupleMember]: ts.NamedTupleMember; [AST_NODE_TYPES.TSNamespaceExportDeclaration]: ts.NamespaceExportDeclaration; [AST_NODE_TYPES.TSNonNullExpression]: ts.NonNullExpression; [AST_NODE_TYPES.TSOptionalType]: ts.OptionalTypeNode; @@ -193,7 +193,10 @@ export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.TSParenthesizedType]: ts.ParenthesizedTypeNode; [AST_NODE_TYPES.TSPropertySignature]: ts.PropertySignature; [AST_NODE_TYPES.TSQualifiedName]: ts.QualifiedName; - [AST_NODE_TYPES.TSRestType]: ts.RestTypeNode; + [AST_NODE_TYPES.TSRestType]: + | ts.RestTypeNode + // for consistency and following babel's choices, a named tuple member with a rest gets converted to a TSRestType + | ts.NamedTupleMember; [AST_NODE_TYPES.TSThisType]: ts.ThisTypeNode; [AST_NODE_TYPES.TSTupleType]: ts.TupleTypeNode; [AST_NODE_TYPES.TSTypeAliasDeclaration]: ts.TypeAliasDeclaration; @@ -275,5 +278,6 @@ export interface EstreeToTsNodeTypes { */ export type TSESTreeToTSNode = Extract< TSNode | ts.Token, + // if this errors, it means that one of the AST_NODE_TYPES is not defined in the above interface EstreeToTsNodeTypes[T['type']] >; diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 2b8505d1fda..010f6b2619d 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -42,6 +42,7 @@ export type TSNode = | ts.TypeQueryNode | ts.TypeLiteralNode | ts.ArrayTypeNode + | ts.NamedTupleMember | ts.TupleTypeNode | ts.OptionalTypeNode | ts.RestTypeNode diff --git a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts index 71d43e07b11..5f613a834f8 100644 --- a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts +++ b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts @@ -400,30 +400,32 @@ tester.addFixturePatternConfig('typescript/basics', { 'abstract-class-with-declare-properties', 'class-with-declare-properties', /** - * TS 3.8 import/export type - * babel coming soon https://github.com/babel/babel/pull/11171 + * [BABEL ERRORED, BUT TS-ESTREE DID NOT] + * This is intentional; we don't error on semantic problems for these cases */ - 'export-type-as', - 'export-type-from-as', - 'export-type-from', + 'catch-clause-with-invalid-annotation', 'export-type-star-from', - 'export-type', - 'import-type-default', 'import-type-error', - 'import-type-named-as', - 'import-type-named', - 'import-type-star-as-ns', /** - * TS 3.8 export * as namespace - * babel uses a representation that does not match the ESTree spec: https://github.com/estree/estree/pull/205 + * Babel reports incorrect location + * https://github.com/babel/babel/issues/11939 */ - 'export-star-as-ns-from', + 'catch-clause-with-annotation', + /** - * TS 4.0 catch clause with type annotation - * Not supported in babel yet + * Optional chaining + * Babel has updated to ESTree's representation, and we haven't yet + * TODO: remove this with the v4 release */ - 'catch-clause-with-annotation', - 'catch-clause-with-invalid-annotation', + 'optional-chain-call-with-non-null-assertion', + 'optional-chain-call-with-parens', + 'optional-chain-call', + 'optional-chain-element-access-with-non-null-assertion', + 'optional-chain-element-access-with-parens', + 'optional-chain-element-access', + 'optional-chain-with-non-null-assertion', + 'optional-chain-with-parens', + 'optional-chain', ], ignoreSourceType: [ /** @@ -439,6 +441,15 @@ tester.addFixturePatternConfig('typescript/basics', { 'type-alias-declaration-export-function-type', 'type-alias-declaration-export-object-type', 'type-alias-declaration-export', + // babel treats type import/export as not a module + 'export-type', + 'export-type-as', + 'export-type-from', + 'export-type-from-as', + 'import-type-default', + 'import-type-named', + 'import-type-named-as', + 'import-type-star-as-ns', ], }); @@ -468,6 +479,14 @@ tester.addFixturePatternConfig('typescript/decorators/property-decorators', { tester.addFixturePatternConfig('typescript/expressions', { fileType: 'ts', + ignore: [ + /** + * Optional chaining + * Babel has updated to ESTree's representation, and we haven't yet + * TODO: remove this with the v4 release + */ + 'optional-call-expression-type-arguments', + ], }); tester.addFixturePatternConfig('typescript/errorRecovery', { diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap index 57f10c4a034..2b7e4bf9e87 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap @@ -2676,6 +2676,14 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-empty.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-named.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-named-optional.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-named-rest.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-named-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-optional.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/types/tuple-rest.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; diff --git a/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-default.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-default.src.ts.shot index ef7bb2fd30a..5fc98a4fa12 100644 --- a/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-default.src.ts.shot +++ b/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-default.src.ts.shot @@ -46,7 +46,7 @@ Object { "line": 1, }, "start": Object { - "column": 7, + "column": 12, "line": 1, }, }, @@ -69,7 +69,7 @@ Object { "type": "Identifier", }, "range": Array [ - 7, + 12, 15, ], "type": "ImportDefaultSpecifier", diff --git a/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-error.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-error.src.ts.shot index caaa033a94d..5b344b78c2c 100644 --- a/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-error.src.ts.shot +++ b/packages/typescript-estree/tests/snapshots/typescript/basics/import-type-error.src.ts.shot @@ -46,7 +46,7 @@ Object { "line": 1, }, "start": Object { - "column": 7, + "column": 12, "line": 1, }, }, @@ -69,7 +69,7 @@ Object { "type": "Identifier", }, "range": Array [ - 7, + 12, 15, ], "type": "ImportDefaultSpecifier", diff --git a/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-optional.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-optional.src.ts.shot new file mode 100644 index 00000000000..f07915f0394 --- /dev/null +++ b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-optional.src.ts.shot @@ -0,0 +1,727 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript types tuple-named-optional.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 4, + 53, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 53, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "elementTypes": Array [ + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "TSStringKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 8, + 17, + ], + "type": "TSNamedTupleMember", + }, + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 29, + ], + "type": "TSNumberKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "b", + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "optional": true, + "range": Array [ + 19, + 29, + ], + "type": "TSNamedTupleMember", + }, + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 52, + "line": 1, + }, + "start": Object { + "column": 35, + "line": 1, + }, + }, + "range": Array [ + 35, + 52, + ], + "type": "TSParenthesizedType", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 36, + "line": 1, + }, + }, + "range": Array [ + 36, + 51, + ], + "type": "TSUnionType", + "types": Array [ + Object { + "loc": Object { + "end": Object { + "column": 42, + "line": 1, + }, + "start": Object { + "column": 36, + "line": 1, + }, + }, + "range": Array [ + 36, + 42, + ], + "type": "TSStringKeyword", + }, + Object { + "loc": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 45, + "line": 1, + }, + }, + "range": Array [ + 45, + 51, + ], + "type": "TSNumberKeyword", + }, + ], + }, + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "name": "c", + "range": Array [ + 31, + 32, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 52, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "optional": true, + "range": Array [ + 31, + 52, + ], + "type": "TSNamedTupleMember", + }, + ], + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 53, + ], + "type": "TSTupleType", + }, + }, + }, + "init": null, + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 53, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 53, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 54, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + "value": "a", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + "value": "b", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 20, + "line": 1, + }, + }, + "range": Array [ + 20, + 21, + ], + "type": "Punctuator", + "value": "?", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "range": Array [ + 21, + 22, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 29, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "range": Array [ + 29, + 30, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Identifier", + "value": "c", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 32, + "line": 1, + }, + }, + "range": Array [ + 32, + 33, + ], + "type": "Punctuator", + "value": "?", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 34, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 35, + "line": 1, + }, + }, + "range": Array [ + 35, + 36, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 42, + "line": 1, + }, + "start": Object { + "column": 36, + "line": 1, + }, + }, + "range": Array [ + 36, + 42, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 44, + "line": 1, + }, + "start": Object { + "column": 43, + "line": 1, + }, + }, + "range": Array [ + 43, + 44, + ], + "type": "Punctuator", + "value": "|", + }, + Object { + "loc": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 45, + "line": 1, + }, + }, + "range": Array [ + 45, + 51, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 52, + "line": 1, + }, + "start": Object { + "column": 51, + "line": 1, + }, + }, + "range": Array [ + 51, + 52, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 53, + "line": 1, + }, + "start": Object { + "column": 52, + "line": 1, + }, + }, + "range": Array [ + 52, + 53, + ], + "type": "Punctuator", + "value": "]", + }, + ], + "type": "Program", +} +`; diff --git a/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-rest.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-rest.src.ts.shot new file mode 100644 index 00000000000..95e5a937bed --- /dev/null +++ b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-rest.src.ts.shot @@ -0,0 +1,529 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript types tuple-named-rest.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 4, + 34, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 34, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "elementTypes": Array [ + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "TSStringKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 8, + 17, + ], + "type": "TSNamedTupleMember", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 33, + ], + "type": "TSRestType", + "typeAnnotation": Object { + "elementType": Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 31, + ], + "type": "TSNumberKeyword", + }, + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 33, + ], + "type": "TSArrayType", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "name": "b", + "range": Array [ + 22, + 23, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 22, + 33, + ], + "type": "TSNamedTupleMember", + }, + }, + ], + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 34, + ], + "type": "TSTupleType", + }, + }, + }, + "init": null, + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 34, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 34, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 35, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + "value": "a", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 22, + ], + "type": "Punctuator", + "value": "...", + }, + Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 23, + ], + "type": "Identifier", + "value": "b", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 31, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 32, + "line": 1, + }, + }, + "range": Array [ + 32, + 33, + ], + "type": "Punctuator", + "value": "]", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 34, + ], + "type": "Punctuator", + "value": "]", + }, + ], + "type": "Program", +} +`; diff --git a/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-type.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-type.src.ts.shot new file mode 100644 index 00000000000..b62f8aacce6 --- /dev/null +++ b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named-type.src.ts.shot @@ -0,0 +1,421 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript types tuple-named-type.src 1`] = ` +Object { + "body": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "name": "Foo", + "range": Array [ + 5, + 8, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 34, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "elementTypes": Array [ + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "range": Array [ + 15, + 21, + ], + "type": "TSStringKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 12, + 13, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 12, + 21, + ], + "type": "TSNamedTupleMember", + }, + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 33, + ], + "type": "TSStringKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "name": "b", + "range": Array [ + 23, + 24, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "optional": true, + "range": Array [ + 23, + 33, + ], + "type": "TSNamedTupleMember", + }, + ], + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 34, + ], + "type": "TSTupleType", + }, + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 35, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 4, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 8, + ], + "type": "Identifier", + "value": "Foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 12, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Identifier", + "value": "a", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 13, + "line": 1, + }, + }, + "range": Array [ + 13, + 14, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "range": Array [ + 15, + 21, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "range": Array [ + 21, + 22, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "Identifier", + "value": "b", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 25, + ], + "type": "Punctuator", + "value": "?", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 26, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 33, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 34, + ], + "type": "Punctuator", + "value": "]", + }, + ], + "type": "Program", +} +`; diff --git a/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named.src.ts.shot new file mode 100644 index 00000000000..0be4c086a37 --- /dev/null +++ b/packages/typescript-estree/tests/snapshots/typescript/types/tuple-named.src.ts.shot @@ -0,0 +1,584 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript types tuple-named.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 4, + 40, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 40, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "elementTypes": Array [ + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "TSNumberKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 8, + 17, + ], + "type": "TSNamedTupleMember", + }, + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 28, + ], + "type": "TSNumberKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "b", + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 19, + 28, + ], + "type": "TSNamedTupleMember", + }, + Object { + "elementType": Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 39, + ], + "type": "TSNumberKeyword", + }, + "label": Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 30, + "line": 1, + }, + }, + "name": "c", + "range": Array [ + 30, + 31, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 30, + "line": 1, + }, + }, + "optional": false, + "range": Array [ + 30, + 39, + ], + "type": "TSNamedTupleMember", + }, + ], + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 40, + ], + "type": "TSTupleType", + }, + }, + }, + "init": null, + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 40, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 41, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 41, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 42, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "[", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Identifier", + "value": "a", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + "value": "b", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 20, + "line": 1, + }, + }, + "range": Array [ + 20, + 21, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 28, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 28, + "line": 1, + }, + }, + "range": Array [ + 28, + 29, + ], + "type": "Punctuator", + "value": ",", + }, + Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 30, + "line": 1, + }, + }, + "range": Array [ + 30, + 31, + ], + "type": "Identifier", + "value": "c", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 39, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 39, + "line": 1, + }, + }, + "range": Array [ + 39, + 40, + ], + "type": "Punctuator", + "value": "]", + }, + Object { + "loc": Object { + "end": Object { + "column": 41, + "line": 1, + }, + "start": Object { + "column": 40, + "line": 1, + }, + }, + "range": Array [ + 40, + 41, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index 66b7db0ea13..e71e59d3eec 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -1,17 +1,28 @@ +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as eslintVisitorKeys from 'eslint-visitor-keys'; interface VisitorKeys { readonly [type: string]: readonly string[] | undefined; } -const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ - // Additional estree nodes. - Import: [], +type GetNodeTypeKeys = Exclude< + keyof Extract, + 'type' | 'loc' | 'range' | 'parent' +>; + +// strictly type the arrays of keys provided to make sure we keep this config in sync with the type defs +type AdditionalKeys = { + readonly [T in AST_NODE_TYPES]?: readonly GetNodeTypeKeys[]; +}; + +const additionalKeys: AdditionalKeys = { // ES2020 ImportExpression: ['source'], + // Additional Properties. ArrayPattern: ['decorators', 'elements', 'typeAnnotation'], ArrowFunctionExpression: ['typeParameters', 'params', 'returnType', 'body'], + CallExpression: ['callee', 'typeParameters', 'arguments'], ClassDeclaration: [ 'decorators', 'id', @@ -30,15 +41,15 @@ const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ 'implements', 'body', ], - TaggedTemplateExpression: ['tag', 'typeParameters', 'quasi'], FunctionDeclaration: ['id', 'typeParameters', 'params', 'returnType', 'body'], FunctionExpression: ['id', 'typeParameters', 'params', 'returnType', 'body'], Identifier: ['decorators', 'typeAnnotation'], MethodDefinition: ['decorators', 'key', 'value'], + NewExpression: ['callee', 'typeParameters', 'arguments'], ObjectPattern: ['decorators', 'properties', 'typeAnnotation'], RestElement: ['decorators', 'argument', 'typeAnnotation'], - NewExpression: ['callee', 'typeParameters', 'arguments'], - CallExpression: ['callee', 'typeParameters', 'arguments'], + TaggedTemplateExpression: ['tag', 'typeParameters', 'quasi'], + // JSX JSXOpeningElement: ['name', 'typeParameters', 'attributes'], JSXClosingFragment: [], @@ -49,7 +60,9 @@ const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ ClassProperty: ['decorators', 'key', 'typeAnnotation', 'value'], Decorator: ['expression'], OptionalCallExpression: ['callee', 'typeParameters', 'arguments'], - OptionalMemberExpression: eslintVisitorKeys.KEYS.MemberExpression, + OptionalMemberExpression: ['object', 'property'], + + // TS-prefixed nodes TSAbstractClassProperty: ['decorators', 'key', 'typeAnnotation', 'value'], TSAbstractKeyword: [], TSAbstractMethodDefinition: ['key', 'value'], @@ -62,8 +75,8 @@ const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ TSCallSignatureDeclaration: ['typeParameters', 'params', 'returnType'], TSClassImplements: ['expression', 'typeParameters'], TSConditionalType: ['checkType', 'extendsType', 'trueType', 'falseType'], - TSConstructSignatureDeclaration: ['typeParameters', 'params', 'returnType'], TSConstructorType: ['typeParameters', 'params', 'returnType'], + TSConstructSignatureDeclaration: ['typeParameters', 'params', 'returnType'], TSDeclareFunction: ['id', 'typeParameters', 'params', 'returnType', 'body'], TSDeclareKeyword: [], TSEmptyBodyFunctionExpression: [ @@ -77,24 +90,25 @@ const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ TSExportAssignment: ['expression'], TSExportKeyword: [], TSExternalModuleReference: ['expression'], + TSFunctionType: ['typeParameters', 'params', 'returnType'], + TSImportEqualsDeclaration: ['id', 'moduleReference'], TSImportType: ['parameter', 'qualifier', 'typeParameters'], - TSInferType: ['typeParameter'], - TSLiteralType: ['literal'], - TSIntersectionType: ['types'], TSIndexedAccessType: ['indexType', 'objectType'], TSIndexSignature: ['parameters', 'typeAnnotation'], + TSInferType: ['typeParameter'], TSInterfaceBody: ['body'], TSInterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'], TSInterfaceHeritage: ['expression', 'typeParameters'], - TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSFunctionType: ['typeParameters', 'params', 'returnType'], + TSIntersectionType: ['types'], + TSLiteralType: ['literal'], TSMappedType: ['typeParameter', 'typeAnnotation'], TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'], TSModuleBlock: ['body'], TSModuleDeclaration: ['id', 'body'], + TSNamedTupleMember: ['elementType'], TSNamespaceExportDeclaration: ['id'], - TSNonNullExpression: ['expression'], TSNeverKeyword: [], + TSNonNullExpression: ['expression'], TSNullKeyword: [], TSNumberKeyword: [], TSObjectKeyword: [], @@ -122,12 +136,14 @@ const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith({ TSTypeParameterDeclaration: ['params'], TSTypeParameterInstantiation: ['params'], TSTypePredicate: ['typeAnnotation', 'parameterName'], - TSTypeReference: ['typeName', 'typeParameters'], TSTypeQuery: ['exprName'], - TSUnionType: ['types'], + TSTypeReference: ['typeName', 'typeParameters'], TSUndefinedKeyword: [], + TSUnionType: ['types'], TSUnknownKeyword: [], TSVoidKeyword: [], -}); +} as const; + +const visitorKeys: VisitorKeys = eslintVisitorKeys.unionWith(additionalKeys); export { visitorKeys, VisitorKeys }; diff --git a/yarn.lock b/yarn.lock index 2a4e539b470..2f7721577ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,13 @@ dependencies: "@babel/highlight" "^7.8.3" +"@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.6.tgz#d9aa1f580abf3b2286ef40b6904d390904c63376" @@ -121,6 +128,11 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + "@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" @@ -135,6 +147,15 @@ "@babel/traverse" "^7.9.6" "@babel/types" "^7.9.6" +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/highlight@^7.8.3": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" @@ -144,11 +165,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.8.3", "@babel/parser@^7.8.6", "@babel/parser@^7.9.6": +"@babel/parser@^7.1.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.6": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.6.tgz#3b1bbb30dabe600cd72db58720998376ff653bc7" integrity sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q== +"@babel/parser@^7.11.3": + version "7.11.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9" + integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA== + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -259,6 +285,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -5881,7 +5916,7 @@ lodash@4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -lodash@^4.11.2, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.2.1: +lodash@^4.11.2, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.2.1: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==