diff --git a/packages/babel-helper-annotate-as-pure/src/index.ts b/packages/babel-helper-annotate-as-pure/src/index.ts index e2644da46e68..f6a92c4fb7ba 100644 --- a/packages/babel-helper-annotate-as-pure/src/index.ts +++ b/packages/babel-helper-annotate-as-pure/src/index.ts @@ -1,5 +1,5 @@ -import { addComment } from "@babel/types"; -import type { Node } from "@babel/types"; +import { addComment, type Node } from "@babel/types"; +import type { NodePath } from "@babel/traverse"; const PURE_ANNOTATION = "#__PURE__"; @@ -7,10 +7,10 @@ const isPureAnnotated = ({ leadingComments }: Node): boolean => !!leadingComments && leadingComments.some(comment => /[@#]__PURE__/.test(comment.value)); -export default function annotateAsPure( - pathOrNode: Node | { node: Node }, -): void { - const node = pathOrNode["node"] || pathOrNode; +export default function annotateAsPure(pathOrNode: Node | NodePath): void { + const node = + // @ts-expect-error Node will not have `node` property + (pathOrNode["node"] || pathOrNode) as Node; if (isPureAnnotated(node)) { return; } diff --git a/packages/babel-helper-builder-binary-assignment-operator-visitor/src/index.ts b/packages/babel-helper-builder-binary-assignment-operator-visitor/src/index.ts index c498d70369d7..7cc8513ac3ed 100644 --- a/packages/babel-helper-builder-binary-assignment-operator-visitor/src/index.ts +++ b/packages/babel-helper-builder-binary-assignment-operator-visitor/src/index.ts @@ -1,6 +1,7 @@ import explode from "@babel/helper-explode-assignable-expression"; import { assignmentExpression, sequenceExpression } from "@babel/types"; import type { Visitor } from "@babel/traverse"; +import type * as t from "@babel/types"; export default function (opts: { build: Function; operator: string }) { const { build, operator } = opts; @@ -10,7 +11,7 @@ export default function (opts: { build: Function; operator: string }) { const { node, scope } = path; if (node.operator !== operator + "=") return; - const nodes = []; + const nodes: t.AssignmentExpression[] = []; // @ts-expect-error todo(flow->ts) const exploded = explode(node.left, nodes, this, scope); nodes.push( diff --git a/packages/babel-helper-check-duplicate-nodes/src/index.ts b/packages/babel-helper-check-duplicate-nodes/src/index.ts index 949c5c2a7871..2f44f4215c79 100644 --- a/packages/babel-helper-check-duplicate-nodes/src/index.ts +++ b/packages/babel-helper-check-duplicate-nodes/src/index.ts @@ -1,20 +1,25 @@ import { VISITOR_KEYS } from "@babel/types"; +import type * as t from "@babel/types"; -export default function checkDuplicateNodes(ast) { +type StackItem = { + node: t.Node; + parent: t.Node | null; +}; +export default function checkDuplicateNodes(ast: t.Node) { if (arguments.length !== 1) { throw new Error("checkDuplicateNodes accepts only one argument: ast"); } // A Map from node to its parent const parentsMap = new Map(); - const hidePrivateProperties = (key, val) => { + const hidePrivateProperties = (key: string, val: unknown) => { // Hides properties like _shadowedFunctionLiteral, // which makes the AST circular if (key[0] === "_") return "[Private]"; return val; }; - const stack = [{ node: ast, parent: null }]; + const stack: StackItem[] = [{ node: ast, parent: null }]; let item; while ((item = stack.pop()) !== undefined) { @@ -36,7 +41,9 @@ export default function checkDuplicateNodes(ast) { parentsMap.set(node, parent); for (const key of keys) { - const subNode = node[key]; + const subNode = + // @ts-expect-error visitor keys must present in node + node[key]; if (Array.isArray(subNode)) { for (const child of subNode) { diff --git a/packages/babel-helper-define-map/src/index.ts b/packages/babel-helper-define-map/src/index.ts index 0653c7991744..c303e022632f 100644 --- a/packages/babel-helper-define-map/src/index.ts +++ b/packages/babel-helper-define-map/src/index.ts @@ -17,8 +17,11 @@ import { toComputedKey, toKeyAlias, } from "@babel/types"; +import type { File } from "@babel/core"; +import type * as t from "@babel/types"; +import type { Scope } from "@babel/traverse"; -function toKind(node: any) { +function toKind(node: t.Property | t.Method) { if (isClassMethod(node) || isObjectMethod(node)) { if (node.kind === "get" || node.kind === "set") { return node.kind; @@ -30,12 +33,32 @@ function toKind(node: any) { const has = Function.prototype.call.bind(Object.prototype.hasOwnProperty); -export function push(mutatorMap: any, node: any, kind: string, file, scope?) { +type DefineMap = { + decorators: t.ArrayExpression; + _computed: boolean; + _inherits: t.Node[]; + _key: t.Expression | t.PrivateName; + value?: t.Expression; + initializer?: t.Expression; + get?: t.Expression; + set?: t.Expression; + kind: "get" | "set" | "value" | "initializer"; +}; + +export type MutatorMap = Record; + +export function push( + mutatorMap: MutatorMap, + node: t.Property | t.Method, + kind: DefineMap["kind"], + file: File, + scope?: Scope, +) { const alias = toKeyAlias(node); // - let map = {} as any; + let map = {} as DefineMap; if (has(mutatorMap, alias)) map = mutatorMap[alias]; mutatorMap[alias] = map; @@ -46,7 +69,10 @@ export function push(mutatorMap: any, node: any, kind: string, file, scope?) { map._key = node.key; - if (node.computed) { + if ( + // @ts-expect-error computed is not in private property + node.computed + ) { map._computed = true; } @@ -69,7 +95,7 @@ export function push(mutatorMap: any, node: any, kind: string, file, scope?) { } if (isProperty(node)) { - value = node.value; + value = node.value as t.Expression; } else if (isObjectMethod(node) || isClassMethod(node)) { value = functionExpression( null, diff --git a/packages/babel-helper-function-name/src/index.ts b/packages/babel-helper-function-name/src/index.ts index fc157b28be35..623b541e4ad1 100644 --- a/packages/babel-helper-function-name/src/index.ts +++ b/packages/babel-helper-function-name/src/index.ts @@ -18,6 +18,7 @@ import { toBindingIdentifierName, } from "@babel/types"; import type * as t from "@babel/types"; +import type { NodePath, Scope, Visitor } from "@babel/traverse"; function getFunctionArity(node: t.Function): number { const count = node.params.findIndex( @@ -26,7 +27,7 @@ function getFunctionArity(node: t.Function): number { return count === -1 ? node.params.length : count; } -const buildPropertyMethodAssignmentWrapper = template(` +const buildPropertyMethodAssignmentWrapper = template.statement(` (function (FUNCTION_KEY) { function FUNCTION_ID() { return FUNCTION_KEY.apply(this, arguments); @@ -40,7 +41,7 @@ const buildPropertyMethodAssignmentWrapper = template(` })(FUNCTION) `); -const buildGeneratorPropertyMethodAssignmentWrapper = template(` +const buildGeneratorPropertyMethodAssignmentWrapper = template.statement(` (function (FUNCTION_KEY) { function* FUNCTION_ID() { return yield* FUNCTION_KEY.apply(this, arguments); @@ -54,8 +55,18 @@ const buildGeneratorPropertyMethodAssignmentWrapper = template(` })(FUNCTION) `); -const visitor = { - "ReferencedIdentifier|BindingIdentifier"(path, state) { +type State = { + name: string; + outerDeclar: t.Identifier; + selfAssignment: boolean; + selfReference: boolean; +}; + +const visitor: Visitor = { + "ReferencedIdentifier|BindingIdentifier"( + path: NodePath, + state, + ) { // check if this node matches our function id if (path.node.name !== state.name) return; @@ -69,7 +80,7 @@ const visitor = { }, }; -function getNameFromLiteralId(id) { +function getNameFromLiteralId(id: t.Literal) { if (isNullLiteral(id)) { return "null"; } @@ -89,7 +100,12 @@ function getNameFromLiteralId(id) { return ""; } -function wrap(state, method, id, scope) { +function wrap( + state: State, + method: t.FunctionExpression | t.ClassExpression, + id: t.Identifier, + scope: Scope, +) { if (state.selfReference) { if (scope.hasBinding(id.name) && !scope.hasGlobal(id.name)) { // we can just munge the local binding @@ -131,12 +147,15 @@ function wrap(state, method, id, scope) { scope.getProgramParent().references[id.name] = true; } -function visit(node, name, scope) { - const state = { +function visit( + node: t.FunctionExpression | t.ClassExpression, + name: string, + scope: Scope, +) { + const state: State = { selfAssignment: false, selfReference: false, outerDeclar: scope.getBindingIdentifier(name), - references: [], name: name, }; @@ -188,7 +207,12 @@ export default function ( parent, scope, id, - }: { node: any; parent?: any; scope: any; id?: any }, + }: { + node: t.FunctionExpression | t.ClassExpression; + parent?: t.Node; + scope: Scope; + id?: any; + }, localBinding = false, supportUnicodeId = false, ) { @@ -215,6 +239,7 @@ export default function ( ) { // always going to reference this method node.id = cloneNode(id); + // @ts-expect-error Fixme: avoid mutating AST nodes node.id[NOT_LOCAL_BINDING] = true; return; } @@ -242,13 +267,14 @@ export default function ( } name = toBindingIdentifierName(name); - id = identifier(name); + const newId = identifier(name); // The id shouldn't be considered a local binding to the function because // we are simply trying to set the function name and not actually create // a local binding. - id[NOT_LOCAL_BINDING] = true; + // @ts-ignore Fixme: avoid mutating AST nodes + newId[NOT_LOCAL_BINDING] = true; const state = visit(node, name, scope); - return wrap(state, node, id, scope) || node; + return wrap(state, node, newId, scope) || node; } diff --git a/packages/babel-helper-hoist-variables/src/index.ts b/packages/babel-helper-hoist-variables/src/index.ts index 1cb3b8a3c4c5..89653ac33af8 100644 --- a/packages/babel-helper-hoist-variables/src/index.ts +++ b/packages/babel-helper-hoist-variables/src/index.ts @@ -4,7 +4,7 @@ import { identifier, } from "@babel/types"; import type * as t from "@babel/types"; -import type { NodePath } from "@babel/traverse"; +import type { NodePath, Visitor } from "@babel/traverse"; export type EmitFunction = ( id: t.Identifier, @@ -19,16 +19,16 @@ type State = { type Unpacked = T extends (infer U)[] ? U : T; -const visitor = { - Scope(path: NodePath, state: State) { +const visitor: Visitor = { + Scope(path, state) { if (state.kind === "let") path.skip(); }, - FunctionParent(path: NodePath) { + FunctionParent(path) { path.skip(); }, - VariableDeclaration(path: NodePath, state: State) { + VariableDeclaration(path, state) { if (state.kind && path.node.kind !== state.kind) return; const nodes = []; diff --git a/packages/babel-helper-member-expression-to-functions/src/index.ts b/packages/babel-helper-member-expression-to-functions/src/index.ts index fd629d54de30..3b8867711a50 100644 --- a/packages/babel-helper-member-expression-to-functions/src/index.ts +++ b/packages/babel-helper-member-expression-to-functions/src/index.ts @@ -95,7 +95,13 @@ function isInDetachedTree(path: NodePath) { const { parentPath, container, listKey } = path; const parentNode = parentPath.node; if (listKey) { - if (container !== parentNode[listKey]) return true; + if ( + container !== + // @ts-expect-error listKey must be a valid parent node key + parentNode[listKey] + ) { + return true; + } } else { if (container !== parentNode) return true; } @@ -208,10 +214,9 @@ const handle = { ); } - const startingProp = startingOptional.isOptionalMemberExpression() - ? "object" - : "callee"; - const startingNode = startingOptional.node[startingProp]; + const startingNode = startingOptional.isOptionalMemberExpression() + ? startingOptional.node.object + : startingOptional.node.callee; const baseNeedsMemoised = scope.maybeGenerateMemoised(startingNode); const baseRef = baseNeedsMemoised ?? startingNode; @@ -281,7 +286,12 @@ const handle = { } const baseMemoised = baseNeedsMemoised - ? assignmentExpression("=", cloneNode(baseRef), cloneNode(startingNode)) + ? assignmentExpression( + "=", + // When base needs memoised, the baseRef must be an identifier + cloneNode(baseRef as t.Identifier), + cloneNode(startingNode), + ) : cloneNode(baseRef); if (willEndPathCastToBoolean) { diff --git a/packages/babel-helper-remap-async-to-generator/src/index.ts b/packages/babel-helper-remap-async-to-generator/src/index.ts index a4df21c8e60e..d15b95842791 100644 --- a/packages/babel-helper-remap-async-to-generator/src/index.ts +++ b/packages/babel-helper-remap-async-to-generator/src/index.ts @@ -1,6 +1,6 @@ /* @noflow */ -import type { NodePath } from "@babel/traverse"; +import type { NodePath, Visitor } from "@babel/traverse"; import wrapFunction from "@babel/helper-wrap-function"; import annotateAsPure from "@babel/helper-annotate-as-pure"; import { @@ -10,8 +10,9 @@ import { isThisExpression, yieldExpression, } from "@babel/types"; +import type * as t from "@babel/types"; -const awaitVisitor = { +const awaitVisitor: Visitor<{ wrapAwait: t.Expression }> = { Function(path) { path.skip(); }, @@ -32,8 +33,8 @@ const awaitVisitor = { export default function ( path: NodePath, helpers: { - wrapAsync: any; - wrapAwait?: any; + wrapAsync: t.Expression; + wrapAwait?: t.Expression; }, noNewArrows?: boolean, ignoreFunctionLength?: boolean, diff --git a/packages/babel-helper-simple-access/src/index.ts b/packages/babel-helper-simple-access/src/index.ts index 2b198edfd961..6e460c069b8b 100644 --- a/packages/babel-helper-simple-access/src/index.ts +++ b/packages/babel-helper-simple-access/src/index.ts @@ -20,7 +20,7 @@ type State = { }; export default function simplifyAccess( path: NodePath, - bindingNames, + bindingNames: Set, // TODO(Babel 8): Remove this includeUpdateExpression: boolean = true, ) { diff --git a/packages/babel-helper-split-export-declaration/src/index.ts b/packages/babel-helper-split-export-declaration/src/index.ts index 25ab91b6a9c1..5737527cece5 100644 --- a/packages/babel-helper-split-export-declaration/src/index.ts +++ b/packages/babel-helper-split-export-declaration/src/index.ts @@ -6,25 +6,33 @@ import { variableDeclaration, variableDeclarator, } from "@babel/types"; - -export default function splitExportDeclaration(exportDeclaration) { - if (!exportDeclaration.isExportDeclaration()) { - throw new Error("Only export declarations can be split."); +import type * as t from "@babel/types"; +import type { NodePath } from "@babel/traverse"; + +export default function splitExportDeclaration( + exportDeclaration: NodePath< + t.ExportDefaultDeclaration | t.ExportNamedDeclaration + >, +) { + if ( + !exportDeclaration.isExportDeclaration() || + exportDeclaration.isExportAllDeclaration() + ) { + throw new Error("Only default and named export declarations can be split."); } // build specifiers that point back to this export declaration - const isDefault = exportDeclaration.isExportDefaultDeclaration(); - const declaration = exportDeclaration.get("declaration"); - const isClassDeclaration = declaration.isClassDeclaration(); - if (isDefault) { + if (exportDeclaration.isExportDefaultDeclaration()) { + const declaration = exportDeclaration.get("declaration"); const standaloneDeclaration = - declaration.isFunctionDeclaration() || isClassDeclaration; + declaration.isFunctionDeclaration() || declaration.isClassDeclaration(); const scope = declaration.isScope() ? declaration.scope.parent : declaration.scope; + // @ts-expect-error id is not defined in expressions other than function/class let id = declaration.node.id; let needBindingRegistration = false; @@ -45,7 +53,11 @@ export default function splitExportDeclaration(exportDeclaration) { const updatedDeclaration = standaloneDeclaration ? declaration : variableDeclaration("var", [ - variableDeclarator(cloneNode(id), declaration.node), + variableDeclarator( + cloneNode(id), + // @ts-expect-error When `standaloneDeclaration` is false, declaration must not be a Function/ClassDeclaration + declaration.node, + ), ]); const updatedExportDeclaration = exportNamedDeclaration(null, [ @@ -60,12 +72,14 @@ export default function splitExportDeclaration(exportDeclaration) { } return exportDeclaration; - } - - if (exportDeclaration.get("specifiers").length > 0) { + } else if ( + // @ts-expect-error TS can not narrow down to NodePath + exportDeclaration.get("specifiers").length > 0 + ) { throw new Error("It doesn't make sense to split exported specifiers."); } + const declaration = exportDeclaration.get("declaration"); const bindingIdentifiers = declaration.getOuterBindingIdentifiers(); const specifiers = Object.keys(bindingIdentifiers).map(name => { diff --git a/packages/babel-plugin-transform-property-mutators/src/index.ts b/packages/babel-plugin-transform-property-mutators/src/index.ts index 8323bda0acfe..abfff41b10c1 100644 --- a/packages/babel-plugin-transform-property-mutators/src/index.ts +++ b/packages/babel-plugin-transform-property-mutators/src/index.ts @@ -9,9 +9,9 @@ export default declare(api => { name: "transform-property-mutators", visitor: { - ObjectExpression(path, file) { + ObjectExpression(path, { file }) { const { node } = path; - let mutatorMap; + let mutatorMap: defineMap.MutatorMap | void; const newProperties = node.properties.filter(function (prop) { if (t.isObjectMethod(prop)) { if (prop.kind === "get" || prop.kind === "set") { diff --git a/packages/babel-traverse/src/scope/index.ts b/packages/babel-traverse/src/scope/index.ts index 06504a5df426..1cfa5add854f 100644 --- a/packages/babel-traverse/src/scope/index.ts +++ b/packages/babel-traverse/src/scope/index.ts @@ -380,9 +380,9 @@ export default class Scope { inited; bindings: { [name: string]: Binding }; - references: object; - globals: object; - uids: object; + references: { [name: string]: true }; + globals: { [name: string]: t.Identifier | t.JSXIdentifier }; + uids: { [name: string]: true }; data: object; crawling: boolean; @@ -798,8 +798,7 @@ export default class Scope { } } - // todo: flow->ts maybe add more specific type - addGlobal(node: Extract) { + addGlobal(node: t.Identifier | t.JSXIdentifier) { this.globals[node.name] = node; }