// @flow import type { Token } from "./tokenizer"; import type { SourceLocation } from "./util/location"; /* * If making any changes to the AST, update: * - This repository: * - This file * - `ast` directory * - Babel repository: * - packages/babel-types/src/definitions * - packages/babel-generators/src/generators */ export type Comment = { type: "CommentBlock" | "CommentLine", value: string, start: number, end: number, loc: SourceLocation, }; export interface NodeBase { start: number, end: number, loc: SourceLocation, range: [number, number], leadingComments?: ?Array, trailingComments?: ?Array, innerComments?: ?Array, extra: { [key: string]: any }, } // Using a union type for `Node` makes type-checking too slow. // Instead, add an index signature to allow a Node to be treated as anything. export type Node = NodeBase & { [key: string]: any }; export type Expression = Node; export type Statement = Node; export type Pattern = | Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern; export type Declaration = | VariableDeclaration | ClassDeclaration | FunctionDeclaration | TsInterfaceDeclaration | TsTypeAliasDeclaration | TsEnumDeclaration | TsModuleDeclaration; export type DeclarationBase = NodeBase & { // TypeScript allows declarations to be prefixed by `declare`. //TODO: a FunctionDeclaration is never "declare", because it's a TSDeclareFunction instead. declare?: true, }; // TODO: Not in spec export type HasDecorators = NodeBase & { decorators?: $ReadOnlyArray, }; export type Identifier = PatternBase & { type: "Identifier", name: string, __clone(): Identifier, // TypeScript only. Used in case of an optional parameter. optional?: ?true, }; export type PrivateName = NodeBase & { type: "PrivateName", name: string, }; // Literals export type Literal = | RegExpLiteral | NullLiteral | StringLiteral | BooleanLiteral | NumericLiteral; export type RegExpLiteral = NodeBase & { type: "RegExpLiteral", pattern: string, flags: RegExp$flags, }; export type NullLiteral = NodeBase & { type: "NullLiteral", }; export type StringLiteral = NodeBase & { type: "StringLiteral", value: string, }; export type BooleanLiteral = NodeBase & { type: "BooleanLiteral", value: boolean, }; export type NumericLiteral = NodeBase & { type: "NumericLiteral", value: number, }; export type BigIntLiteral = NodeBase & { type: "BigIntLiteral", value: number, }; // Programs export type BlockStatementLike = Program | BlockStatement; export type File = NodeBase & { type: "File", program: Program, comments: $ReadOnlyArray, tokens: $ReadOnlyArray, }; export type Program = NodeBase & { type: "Program", sourceType: "script" | "module", body: Array, // TODO: $ReadOnlyArray directives: $ReadOnlyArray, // TODO: Not in spec }; // Functions export type Function = | NormalFunction | ArrowFunctionExpression | ObjectMethod | ClassMethod; export type NormalFunction = FunctionDeclaration | FunctionExpression; export type BodilessFunctionOrMethodBase = HasDecorators & { // TODO: Remove this. Should not assign "id" to methods. // https://github.com/babel/babylon/issues/535 id: ?Identifier, params: $ReadOnlyArray, body: BlockStatement, generator: boolean, async: boolean, // TODO: All not in spec expression: boolean, typeParameters?: ?TypeParameterDeclaration, returnType?: ?TypeAnnotation, }; export type BodilessFunctionBase = BodilessFunctionOrMethodBase & { id: ?Identifier, }; export type FunctionBase = BodilessFunctionBase & { body: BlockStatement, }; // Statements export type ExpressionStatement = NodeBase & { type: "ExpressionStatement", expression: Expression, }; export type BlockStatement = NodeBase & { type: "BlockStatement", body: Array, // TODO: $ReadOnlyArray directives: $ReadOnlyArray, }; export type EmptyStatement = NodeBase & { type: "EmptyStatement", }; export type DebuggerStatement = NodeBase & { type: "DebuggerStatement", }; export type WithStatement = NodeBase & { type: "WithStatement", object: Expression, body: Statement, }; export type ReturnStatement = NodeBase & { type: "ReturnStatement", argument: ?Expression, }; export type LabeledStatement = NodeBase & { type: "LabeledStatement", label: Identifier, body: Statement, }; export type BreakStatement = NodeBase & { type: "BreakStatement", label: ?Identifier, }; export type ContinueStatement = NodeBase & { type: "ContinueStatement", label: ?Identifier, }; // Choice export type IfStatement = NodeBase & { type: "IfStatement", test: Expression, consequent: Statement, alternate: ?Statement, }; export type SwitchStatement = NodeBase & { type: "SwitchStatement", discriminant: Expression, cases: $ReadOnlyArray, }; export type SwitchCase = NodeBase & { type: "SwitchCase", test: ?Expression, consequent: $ReadOnlyArray, }; // Exceptions export type ThrowStatement = NodeBase & { type: "ThrowStatement", argument: Expression, }; export type TryStatement = NodeBase & { type: "TryStatement", block: BlockStatement, handler: CatchClause | null, finalizer: BlockStatement | null, guardedHandlers: $ReadOnlyArray, // TODO: Not in spec }; export type CatchClause = NodeBase & { type: "CatchClause", param: Pattern, body: BlockStatement, }; // Loops export type WhileStatement = NodeBase & { type: "WhileStatement", test: Expression, body: Statement, }; export type DoWhileStatement = NodeBase & { type: "DoWhileStatement", body: Statement, test: Expression, }; export type ForLike = ForStatement | ForInOf; export type ForStatement = NodeBase & { type: "ForStatement", init: ?(VariableDeclaration | Expression), test: ?Expression, update: ?Expression, body: Statement, }; export type ForInOf = ForInStatement | ForOfStatement; export type ForInOfBase = NodeBase & { type: "ForInStatement", left: VariableDeclaration | Expression, right: Expression, body: Statement, }; export type ForInStatement = ForInOfBase & { type: "ForInStatement", // TODO: Shouldn't be here, but have to declare it because it's assigned to a ForInOf unconditionally. await: boolean, }; export type ForOfStatement = ForInOfBase & { type: "ForOfStatement", await: boolean, }; // Declarations export type OptFunctionDeclaration = FunctionBase & DeclarationBase & { type: "FunctionDeclaration", }; export type FunctionDeclaration = OptFunctionDeclaration & { id: Identifier, }; export type VariableDeclaration = DeclarationBase & HasDecorators & { type: "VariableDeclaration", declarations: $ReadOnlyArray, kind: "var" | "let" | "const", }; export type VariableDeclarator = NodeBase & { type: "VariableDeclarator", id: Pattern, init: ?Expression, }; // Misc export type Decorator = NodeBase & { type: "Decorator", expression: Expression, }; export type Directive = NodeBase & { type: "Directive", value: DirectiveLiteral, }; export type DirectiveLiteral = StringLiteral & { type: "DirectiveLiteral" }; // Expressions export type Super = NodeBase & { type: "Super" }; export type Import = NodeBase & { type: "Import" }; export type ThisExpression = NodeBase & { type: "ThisExpression" }; export type ArrowFunctionExpression = FunctionBase & { type: "ArrowFunctionExpression", body: BlockStatement | Expression, }; export type YieldExpression = NodeBase & { type: "YieldExpression", argument: ?Expression, delegate: boolean, }; export type AwaitExpression = NodeBase & { type: "AwaitExpression", argument: ?Expression, }; export type ArrayExpression = NodeBase & { type: "ArrayExpression", elements: $ReadOnlyArray, }; export type ObjectExpression = NodeBase & { type: "ObjectExpression", properties: $ReadOnlyArray, }; export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember; export type ObjectMember = ObjectProperty | ObjectMethod; export type ObjectMemberBase = NodeBase & { key: Expression, computed: boolean, value: Expression, decorators: $ReadOnlyArray, kind?: "get" | "set" | "method", method: boolean, // TODO: Not in spec variance?: ?FlowVariance, // TODO: Not in spec }; export type ObjectProperty = ObjectMemberBase & { type: "ObjectProperty", shorthand: boolean, }; export type ObjectMethod = ObjectMemberBase & MethodBase & { type: "ObjectMethod", kind: "get" | "set" | "method", // Never "constructor" }; export type FunctionExpression = MethodBase & { kind?: void, // never set type: "FunctionExpression", }; // Unary operations export type UnaryExpression = NodeBase & { type: "UnaryExpression", operator: UnaryOperator, prefix: boolean, argument: Expression, }; export type UnaryOperator = | "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; export type UpdateExpression = NodeBase & { type: "UpdateExpression", operator: UpdateOperator, argument: Expression, prefix: boolean, }; export type UpdateOperator = "++" | "--"; // Binary operations export type BinaryExpression = NodeBase & { type: "BinaryExpression", operator: BinaryOperator, left: Expression, right: Expression, }; export type BinaryOperator = | "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof"; export type AssignmentExpression = NodeBase & { type: "AssignmentExpression", operator: AssignmentOperator, left: Pattern | Expression, right: Expression, }; export type AssignmentOperator = | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&="; export type LogicalExpression = NodeBase & { type: "LogicalExpression", operator: LogicalOperator, left: Expression, right: Expression, }; export type LogicalOperator = "||" | "&&"; export type SpreadElement = NodeBase & { type: "SpreadElement", argument: Expression, }; export type MemberExpression = NodeBase & { type: "MemberExpression", object: Expression | Super, property: Expression, computed: boolean, }; export type BindExpression = NodeBase & { type: "BindExpression", object: $ReadOnlyArray, callee: $ReadOnlyArray, }; export type ConditionalExpression = NodeBase & { type: "ConditionalExpression", test: Expression, alternate: Expression, consequent: Expression, }; export type CallOrNewBase = NodeBase & { callee: Expression | Super | Import, arguments: Array, // TODO: $ReadOnlyArray typeParameters?: ?TypeParameterInstantiation, // TODO: Not in spec }; export type CallExpression = CallOrNewBase & { type: "CallExpression", }; export type NewExpression = CallOrNewBase & { type: "NewExpression", optional?: boolean, // TODO: Not in spec }; export type SequenceExpression = NodeBase & { type: "SequenceExpression", expressions: $ReadOnlyArray, }; // Template Literals export type TemplateLiteral = NodeBase & { type: "TemplateLiteral", quasis: $ReadOnlyArray, expressions: $ReadOnlyArray, }; export type TaggedTmplateExpression = NodeBase & { type: "TaggedTemplateExpression", tag: Expression, quasi: TemplateLiteral, }; export type TemplateElement = NodeBase & { type: "TemplateElement", tail: boolean, value: { cooked: string, raw: string, }, }; // Patterns // TypeScript access modifiers export type Accessibility = "public" | "protected" | "private"; export type PatternBase = HasDecorators & { // TODO: All not in spec // Flow/TypeScript only: typeAnnotation?: ?TypeAnnotation, }; export type AssignmentProperty = ObjectProperty & { value: Pattern, }; export type ObjectPattern = PatternBase & { type: "ObjectPattern", properties: $ReadOnlyArray, }; export type ArrayPattern = PatternBase & { type: "ArrayPattern", elements: $ReadOnlyArray, }; export type RestElement = PatternBase & { type: "RestElement", argument: Pattern, }; export type AssignmentPattern = PatternBase & { type: "AssignmentPattern", left: Pattern, right: Expression, }; // Classes export type Class = ClassDeclaration | ClassExpression; export type ClassBase = HasDecorators & { id: ?Identifier, superClass: ?Expression, body: ClassBody, decorators: $ReadOnlyArray, // TODO: All not in spec typeParameters?: ?TypeParameterDeclaration, superTypeParameters?: ?TypeParameterInstantiation, implements?: | ?$ReadOnlyArray | $ReadOnlyArray, }; export type ClassBody = NodeBase & { type: "ClassBody", body: Array, // TODO: $ReadOnlyArray }; export type ClassMemberBase = NodeBase & HasDecorators & { static: boolean, computed: boolean, // TypeScript only: accessibility?: ?Accessibility, abstract?: ?true, optional?: ?true, }; export type ClassMember = | ClassMethod | ClassProperty | ClassPrivateProperty | TsIndexSignature; export type MethodLike = | ObjectMethod | FunctionExpression | ClassMethod | TSDeclareMethod; export type MethodBase = FunctionBase & { +kind: MethodKind, }; export type MethodKind = "constructor" | "method" | "get" | "set"; export type ClassMethodOrDeclareMethodCommon = ClassMemberBase & { type: "ClassMethod", key: Expression, kind: MethodKind, static: boolean, decorators: $ReadOnlyArray, }; export type ClassMethod = MethodBase & ClassMethodOrDeclareMethodCommon & { variance?: ?FlowVariance, // TODO: Not in spec }; export type ClassProperty = ClassMemberBase & { type: "ClassProperty", key: Expression, value: ?Expression, // TODO: Not in spec that this is nullable. typeAnnotation?: ?TypeAnnotation, // TODO: Not in spec variance?: ?FlowVariance, // TODO: Not in spec // TypeScript only: (TODO: Not in spec) readonly?: true, }; export type ClassPrivateProperty = NodeBase & { type: "ClassPrivateProperty", key: Identifier, value: ?Expression, // TODO: Not in spec that this is nullable. static: boolean, }; export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { type: "ClassDeclaration", // TypeScript only abstract?: ?true, }; export type ClassDeclaration = OptClassDeclaration & { id: Identifier, }; export type ClassExpression = ClassBase & { type: "ClassExpression" }; export type MetaProperty = NodeBase & { type: "MetaProperty", meta: Identifier, property: Identifier, }; // Modules export type ModuleDeclaration = AnyImport | AnyExport; export type AnyImport = ImportDeclaration | TsImportEqualsDeclaration; export type AnyExport = | ExportNamedDeclaration | ExportDefaultDeclaration | ExportAllDeclaration | TsExportAssignment; export type ModuleSpecifier = NodeBase & { local: Identifier, }; // Imports export type ImportDeclaration = NodeBase & { type: "ImportDeclaration", // TODO: $ReadOnlyArray specifiers: Array< ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier, >, source: Literal, importKind?: "type" | "typeof" | "value", // TODO: Not in spec }; export type ImportSpecifier = ModuleSpecifier & { type: "ImportSpecifier", imported: Identifier, }; export type ImportDefaultSpecifier = ModuleSpecifier & { type: "ImportDefaultSpecifier", }; export type ImportNamespaceSpecifier = ModuleSpecifier & { type: "ImportNamespaceSpecifier", }; // Exports export type ExportNamedDeclaration = NodeBase & { type: "ExportNamedDeclaration", declaration: ?Declaration, specifiers: $ReadOnlyArray, source: ?Literal, exportKind?: "type" | "value", // TODO: Not in spec }; export type ExportSpecifier = NodeBase & { type: "ExportSpecifier", exported: Identifier, }; export type ExportDefaultDeclaration = NodeBase & { type: "ExportDefaultDeclaration", declaration: | OptFunctionDeclaration | OptTSDeclareFunction | OptClassDeclaration | Expression, }; export type ExportAllDeclaration = NodeBase & { type: "ExportAllDeclaration", source: Literal, }; // JSX (TODO: Not in spec) export type JSXIdentifier = Node; export type JSXNamespacedName = Node; export type JSXMemberExpression = Node; export type JSXEmptyExpression = Node; export type JSXSpreadChild = Node; export type JSXExpressionContainer = Node; export type JSXAttribute = Node; export type JSXOpeningElement = Node; export type JSXClosingElement = Node; export type JSXElement = Node; // Flow/TypeScript common (TODO: Not in spec) export type TypeAnnotation = NodeBase & { type: "TypeAnnotation", typeAnnotation: TsType | FlowTypeAnnotation, }; export type TypeParameterDeclaration = NodeBase & { type: "TypeParameterDeclaration", params: $ReadOnlyArray, }; export type TypeParameter = NodeBase & { type: "TypeParameter", name: string, constraint?: TsType, default?: TsType, }; export type TypeParameterInstantiation = NodeBase & { type: "TypeParameterInstantiation", params: $ReadOnlyArray | $ReadOnlyArray, }; // Flow (TODO: Not in spec) export type TypeCastExpression = NodeBase & { type: "TypeCastExpression", expression: Expression, typeAnnotation: TypeAnnotation, }; export type FlowType = Node; export type FlowPredicate = Node; export type FlowDeclare = Node; export type FlowDeclareClass = Node; export type FlowDeclareExportDeclaration = Node; export type FlowDeclareFunction = Node; export type FlowDeclareVariable = Node; export type FlowDeclareModule = Node; export type FlowDeclareModuleExports = Node; export type FlowDeclareTypeAlias = Node; export type FlowDeclareInterface = Node; export type FlowInterface = Node; export type FlowInterfaceExtends = Node; export type FlowTypeAlias = Node; export type FlowObjectTypeIndexer = Node; export type FlowFunctionTypeAnnotation = Node; export type FlowObjectTypeProperty = Node; export type FlowObjectTypeSpreadProperty = Node; export type FlowObjectTypeCallProperty = Node; export type FlowObjectTypeAnnotation = Node; export type FlowQualifiedTypeIdentifier = Node; export type FlowGenericTypeAnnotation = Node; export type FlowTypeofTypeAnnotation = Node; export type FlowTupleTypeAnnotation = Node; export type FlowFunctionTypeParam = Node; export type FlowTypeAnnotation = Node; export type FlowVariance = Node; export type FlowClassImplements = Node; // estree export type EstreeProperty = NodeBase & { type: "Property", shorthand: boolean, key: Expression, computed: boolean, value: Expression, decorators: $ReadOnlyArray, kind?: "get" | "set" | "init", variance?: ?FlowVariance, }; // === === === === // TypeScript // === === === === // Note: A type named `TsFoo` is based on TypeScript's `FooNode` type, // defined in https://github.com/Microsoft/TypeScript/blob/master/src/compiler/types.ts // Differences: // * Change `NodeArray` to just `$ReadOnlyArray`. // * Don't give nodes a "modifiers" list; use boolean flags instead, // and only allow modifiers that are not considered errors. // * A property named `type` must be renamed to `typeAnnotation` to avoid conflict with the node's type. // * Sometimes TypeScript allows to parse something which will be a grammar error later; // in babylon these cause exceptions, so the AST format is stricter. // ================ // Misc // ================ export type TSParameterProperty = HasDecorators & { // Note: This has decorators instead of its parameter. type: "TSParameterProperty", // At least one of `accessibility` or `readonly` must be set. accessibility?: ?Accessibility, readonly?: ?true, parameter: Identifier | AssignmentPattern, }; export type OptTSDeclareFunction = BodilessFunctionBase & DeclarationBase & { type: "TSDeclareFunction", }; export type TSDeclareFunction = OptTSDeclareFunction & { id: Identifier, }; export type TSDeclareMethod = BodilessFunctionOrMethodBase & ClassMethodOrDeclareMethodCommon & { type: "TSDeclareMethod", +kind: MethodKind, }; export type TsQualifiedName = NodeBase & { type: "TSQualifiedName", left: TsEntityName, right: Identifier, }; export type TsEntityName = Identifier | TsQualifiedName; export type TsSignatureDeclaration = | TsCallSignatureDeclaration | TsConstructSignatureDeclaration | TsMethodSignature | TsFunctionType | TsConstructorType; export type TsSignatureDeclarationOrIndexSignatureBase = NodeBase & { // Not using TypeScript's "ParameterDeclaration" here, since it's inconsistent with regular functions. parameters: $ReadOnlyArray, typeAnnotation: ?TypeAnnotation, }; export type TsSignatureDeclarationBase = TsSignatureDeclarationOrIndexSignatureBase & { typeParameters: ?TypeParameterDeclaration, }; // ================ // TypeScript type members (for type literal / interface / class) // ================ export type TsTypeElement = | TsCallSignatureDeclaration | TsConstructSignatureDeclaration | TsPropertySignature | TsMethodSignature | TsIndexSignature; export type TsCallSignatureDeclaration = TsSignatureDeclarationBase & { type: "TSCallSignatureDeclaration", }; export type TsConstructSignatureDeclaration = TsSignatureDeclarationBase & { type: "TSConstructSignature", }; export type TsNamedTypeElementBase = NodeBase & { // Not using TypeScript's `PropertyName` here since we don't have a `ComputedPropertyName` node type. // This is usually an Identifier but may be e.g. `Symbol.iterator` if `computed` is true. key: Expression, computed: boolean, optional?: true, }; export type TsPropertySignature = TsNamedTypeElementBase & { type: "TSPropertySignature", readonly?: true, typeAnnotation?: TypeAnnotation, initializer?: Expression, }; export type TsMethodSignature = TsSignatureDeclarationBase & TsNamedTypeElementBase & { type: "TSMethodSignature", }; // *Not* a ClassMemberBase: Can't have accessibility, can't be abstract, can't be optional. export type TsIndexSignature = TsSignatureDeclarationOrIndexSignatureBase & { readonly?: true, type: "TSIndexSignature", // Note: parameters.length must be 1. }; // ================ // TypeScript types // ================ export type TsType = | TsKeywordType | TsThisType | TsFunctionOrConstructorType | TsTypeReference | TsTypeQuery | TsTypeLiteral | TsArrayType | TsTupleType | TsUnionOrIntersectionType | TsParenthesizedType | TsTypeOperator | TsIndexedAccessType | TsMappedType | TsLiteralType // TODO: This probably shouldn't be included here. | TsTypePredicate; export type TsTypeBase = NodeBase; export type TsKeywordTypeType = | "TSAnyKeyword" | "TSNumberKeyword" | "TSObjectKeyword" | "TSBooleanKeyword" | "TSStringKeyword" | "TSSymbolKeyword" | "TSVoidKeyword" | "TSUndefinedKeyword" | "TSNullKeyword" | "TSNeverKeyword"; export type TsKeywordType = TsTypeBase & { type: TsKeywordTypeType, }; export type TsThisType = TsTypeBase & { type: "TSThisType", }; export type TsFunctionOrConstructorType = TsFunctionType | TsConstructorType; export type TsFunctionType = TsTypeBase & TsSignatureDeclarationBase & { type: "TSFunctionType", typeAnnotation: TypeAnnotation, // not optional }; export type TsConstructorType = TsTypeBase & TsSignatureDeclarationBase & { type: "TSConstructorType", typeAnnotation: TypeAnnotation, }; export type TsTypeReference = TsTypeBase & { type: "TSTypeReference", typeName: TsEntityName, typeParameters?: TypeParameterInstantiation, }; export type TsTypePredicate = TsTypeBase & { type: "TSTypePredicate", parameterName: Identifier | TsThisType, typeAnnotation: TypeAnnotation, }; // `typeof` operator export type TsTypeQuery = TsTypeBase & { type: "TSTypeQuery", exprName: TsEntityName, }; export type TsTypeLiteral = TsTypeBase & { type: "TSTypeLiteral", members: $ReadOnlyArray, }; export type TsArrayType = TsTypeBase & { type: "TSArrayType", elementType: TsType, }; export type TsTupleType = TsTypeBase & { type: "TSTupleType", elementTypes: $ReadOnlyArray, }; export type TsUnionOrIntersectionType = TsUnionType | TsIntersectionType; export type TsUnionOrIntersectionTypeBase = TsTypeBase & { types: $ReadOnlyArray, }; export type TsUnionType = TsUnionOrIntersectionTypeBase & { type: "TSUnionType", }; export type TsIntersectionType = TsUnionOrIntersectionTypeBase & { type: "TSIntersectionType", }; export type TsParenthesizedType = TsTypeBase & { type: "TSParenthesizedType", typeAnnotation: TsType, }; export type TsTypeOperator = TsTypeBase & { type: "TSTypeOperator", operator: "keyof", typeAnnotation: TsType, }; export type TsIndexedAccessType = TsTypeBase & { type: "TSIndexedAccessType", objectType: TsType, indexType: TsType, }; export type TsMappedType = TsTypeBase & { type: "TSMappedType", readonly?: true, typeParameter: TypeParameter, optional?: true, typeAnnotation: ?TsType, }; export type TsLiteralType = TsTypeBase & { type: "TSLiteralType", literal: NumericLiteral | StringLiteral | BooleanLiteral, }; // ================ // TypeScript declarations // ================ export type TsInterfaceDeclaration = DeclarationBase & { type: "TSInterfaceDeclaration", id: Identifier, typeParameters: ?TypeParameterDeclaration, // TS uses "heritageClauses", but want this to resemble ClassBase. extends?: $ReadOnlyArray, body: TSInterfaceBody, }; export type TSInterfaceBody = NodeBase & { type: "TSInterfaceBody", body: $ReadOnlyArray, }; export type TsExpressionWithTypeArguments = TsTypeBase & { type: "TSExpressionWithTypeArguments", expression: TsEntityName, typeParameters?: TypeParameterInstantiation, }; export type TsTypeAliasDeclaration = DeclarationBase & { type: "TSTypeAliasDeclaration", id: Identifier, typeParameters: ?TypeParameterDeclaration, typeAnnotation: TsType, }; export type TsEnumDeclaration = DeclarationBase & { type: "TSEnumDeclaration", const?: true, id: Identifier, members: $ReadOnlyArray, }; export type TsEnumMember = NodeBase & { type: "TSEnumMemodulmber", id: Identifier | StringLiteral, initializer?: Expression, }; export type TsModuleDeclaration = DeclarationBase & { type: "TSModuleDeclaration", global?: true, // In TypeScript, this is only available through `node.flags`. id: TsModuleName, body: TsNamespaceBody, }; // `namespace A.B { }` is a namespace named `A` with another TsNamespaceDeclaration as its body. export type TsNamespaceBody = TsModuleBlock | TsNamespaceDeclaration; export type TsModuleBlock = NodeBase & { type: "TSModuleBlock", body: $ReadOnlyArray, }; export type TsNamespaceDeclaration = TsModuleDeclaration & { id: Identifier, body: TsNamespaceBody, }; export type TsModuleName = Identifier | StringLiteral; export type TsImportEqualsDeclaration = NodeBase & { type: "TSImportEqualsDeclaration", isExport: boolean, id: Identifier, moduleReference: TsModuleReference, }; export type TsModuleReference = TsEntityName | TsExternalModuleReference; export type TsExternalModuleReference = NodeBase & { type: "TSExternalModuleReference", expression: StringLiteral, }; // TypeScript's own parser uses ExportAssignment for both `export default` and `export =`. // But for babylon, `export default` is an ExportDefaultDeclaration, // so a TsExportAssignment is always `export =`. export type TsExportAssignment = NodeBase & { type: "TSExportAssignment", expression: Expression, }; export type TsNamespaceExportDeclaration = NodeBase & { type: "TSNamespaceExportDeclaration", id: Identifier, }; // ================ // TypeScript expressions // ================ export type TsTypeAssertionLikeBase = NodeBase & { expression: Expression, typeAnnotation: TsType, }; export type TsAsExpression = TsTypeAssertionLikeBase & { type: "TSAsExpression", }; export type TsTypeAssertion = TsTypeAssertionLikeBase & { type: "TSTypeAssertion", typeAnnotation: TsType, expression: Expression, }; export type TsNonNullExpression = NodeBase & { type: "TSNonNullExpression", expression: Expression, };