Babel helper utility for skipping transparent expression wrappers like type assertions and parentheses in AST traversal
npx @tessl/cli install tessl/npm-babel--helper-skip-transparent-expression-wrappers@7.25.0@babel/helper-skip-transparent-expression-wrappers is a utility package that provides functions to skip "transparent" expression wrappers in Babel AST nodes. Transparent wrappers are expressions that don't affect runtime behavior, such as TypeScript type assertions, Flow type casts, and parenthesized expressions. This helper is essential for Babel plugins that need to analyze the actual expression logic without being confused by type annotations or extra parentheses.
This package is primarily used internally by other Babel plugins and tools during AST traversal and transformation phases, allowing them to focus on the semantic content of expressions rather than their syntactic wrappers.
npm install @babel/helper-skip-transparent-expression-wrappersimport {
isTransparentExprWrapper,
skipTransparentExprWrappers,
skipTransparentExprWrapperNodes,
TransparentExprWrapper
} from "@babel/helper-skip-transparent-expression-wrappers";For CommonJS:
const {
isTransparentExprWrapper,
skipTransparentExprWrappers,
skipTransparentExprWrapperNodes
} = require("@babel/helper-skip-transparent-expression-wrappers");import { skipTransparentExprWrappers, isTransparentExprWrapper } from "@babel/helper-skip-transparent-expression-wrappers";
import { NodePath } from "@babel/traverse";
import * as t from "@babel/types";
// In a Babel plugin
export default function myPlugin() {
return {
visitor: {
CallExpression(path: NodePath<t.CallExpression>) {
// Skip transparent wrappers to get the actual callee
const calleePath = skipTransparentExprWrappers(path.get("callee"));
// Now analyze the unwrapped callee
if (t.isIdentifier(calleePath.node)) {
console.log("Function name:", calleePath.node.name);
}
},
Expression(path: NodePath<t.Expression>) {
// Check if current node is a transparent wrapper
if (isTransparentExprWrapper(path.node)) {
console.log("Found transparent wrapper:", path.node.type);
}
}
}
};
}Tests whether an AST node is a transparent expression wrapper that can be safely skipped during analysis.
/**
* Checks if a node is a transparent expression wrapper
* @param node - The AST node to check
* @returns Type predicate indicating if node is a transparent wrapper
*/
function isTransparentExprWrapper(
node: t.Node
): node is TransparentExprWrapper;Traverses through transparent expression wrappers in a NodePath, returning the path to the first non-transparent expression.
/**
* Traverses a NodePath, skipping transparent expression wrappers
* @param path - The NodePath to traverse
* @returns The NodePath after skipping transparent wrappers
*/
function skipTransparentExprWrappers(
path: NodePath<t.Expression>
): NodePath<t.Expression>;Traverses through transparent expression wrappers directly on AST nodes, returning the first non-transparent expression node.
/**
* Traverses AST nodes directly, skipping transparent expression wrappers
* @param node - The AST node to traverse
* @returns The node after skipping transparent wrappers
*/
function skipTransparentExprWrapperNodes(
node: t.Expression | t.Super
): t.Expression | t.Super;/**
* Union type representing all expression wrapper types that are considered "transparent"
* These are expressions that don't affect runtime behavior and can be safely skipped
*/
type TransparentExprWrapper =
| t.TSAsExpression // TypeScript: expr as Type
| t.TSSatisfiesExpression // TypeScript: expr satisfies Type
| t.TSTypeAssertion // TypeScript: <Type>expr
| t.TSNonNullExpression // TypeScript: expr!
| t.TypeCastExpression // Flow: (expr: Type)
| t.ParenthesizedExpression; // Extra parentheses: (expr)This helper recognizes and skips the following transparent expression wrapper types:
as syntax (expr as Type)expr satisfies Type)<Type>expr)expr!)(expr: Type))(expr))These wrappers are considered "transparent" because they don't affect the runtime behavior of the code - they are either removed during compilation (type annotations) or have no semantic effect (parentheses).