function visit(swcPath, visitor, traversalContext) {
  if (visitor.enter) {
    // @ts-expect-error
    visitor.enter(swcPath);
  }

  if (isRootNode(swcPath.node) && visitor.root) {
    // @ts-expect-error
    visitor.root(swcPath);
  }

  // Later, consider https://github.com/babel/babel/blob/b1e73d6f961065c56427ffa89c130beea8321d3b/packages/babel-traverse/src/traverse-node.ts#L28
  if (typeof visitor[swcPath.node.type] === 'function') {
    // @ts-expect-error
    visitor[swcPath.node.type](swcPath);
  }
  // @ts-expect-error
  else if (visitor[swcPath.node.type]?.enter) {
    // @ts-expect-error
    visitor[swcPath.node.type].enter(swcPath);
  }
  // @ts-expect-error
  if (visitor[swcPath.node.type]?.exit) {
    // Let visitTree know that we should visit on exit
    // @ts-expect-error
    traversalContext.visitOnExitFns.push(() => visitor[swcPath.node.type].exit(swcPath));
  }
}
@param {SwcPath} swcPath
@param {SwcVisitor} visitor
@param {SwcTraversalContext} traversalContext