graphql/language/visiting

Functions

visit()

Overload 1

visit() will walk through an AST using a depth-first traversal, calling the visitor’s enter function at each node in the traversal, and calling the leave function after visiting that node and all of its child nodes.

By returning different values from the enter and leave functions, the behavior of the visitor can be altered, including skipping over a sub-tree of the AST (by returning false), editing the AST by returning a value or null to remove the value, or to stop the whole traversal by returning BREAK.

When using visit() to edit an AST, the original AST will not be modified, and a new version of the AST with the changes applied will be returned from the visit function.

Type Parameters
NameConstraintDefaultDescription
NASTNodeThe root AST node type returned when visiting without reducing.

Signature:

visit<N extends ASTNode>(root: N, visitor: ASTVisitor, visitorKeys?: ASTVisitorKeyMap): N
Arguments
NameTypeDefaultDescription
rootNThe AST node at which to start traversal.
visitorASTVisitorThe visitor or reducer functions to call while traversing.
visitorKeys?ASTVisitorKeyMapQueryDocumentKeysOptional map of child keys to visit for each AST node kind.
Returns
TypeDescription
NThe original AST, an edited AST, or a reduced value depending on the visitor.
Example 1

The return value of a visitor function controls traversal and editing:

import { BREAK, parse, visit } from 'graphql/language';
 
const document = parse('{ hero { name } }');
const editedAST = visit(document, {
  enter(node, key, parent, path, ancestors) {
    // @return
    //   undefined: no action
    //   false: skip visiting this node
    //   BREAK: stop visiting altogether
    //   null: delete this node
    //   any value: replace this node with the returned value
  },
  leave(node, key, parent, path, ancestors) {
    // @return
    //   undefined: no action
    //   false: no action
    //   BREAK: stop visiting altogether
    //   null: delete this node
    //   any value: replace this node with the returned value
  }
});
 
// editedAST is the original document unless a visitor returns an edit.

Alternatively to providing enter() and leave() functions, a visitor can instead provide functions named the same as the kinds of AST nodes, or enter/leave visitors at a named key, leading to three permutations of the visitor API:

Example 2

Named visitors are triggered when entering a node of a specific kind:

import { parse, visit } from 'graphql/language';
 
const document = parse('{ hero { name } }');
visit(document, {
  Field(node) {
    // enter the "Field" node
  }
})
 
// The Field visitor runs for "hero" and "name".
Example 3

Named enter and leave visitors are triggered before and after a node’s children:

import { parse, visit } from 'graphql/language';
 
const document = parse('{ hero { name } }');
visit(document, {
  Field: {
    enter(node) {
      // enter the "Field" node
    }
    leave(node) {
      // leave the "Field" node
    }
  }
})
 
// The enter handler runs before children; leave runs after children.
Example 4

Generic visitors are triggered when entering and leaving any node:

import { parse, visit } from 'graphql/language';
 
const document = parse('{ hero { name } }');
visit(document, {
  enter(node) {
    // enter any node
  },
  leave(node) {
    // leave any node
  }
})
 
// The generic handlers run for every node kind.

Overload 2

Traverses an AST with reducer callbacks and returns the reduced value.

Type Parameters
NameConstraintDefaultDescription
RThe value produced by reducer visitor callbacks.

Signature:

visit<R>(root: ASTNode, visitor: {
readonly [NodeT in ASTNode as NodeT[‘kind’]]?: {
readonly enter?: ASTVisitFn<NodeT>;
readonly leave: ASTReducerFn<NodeT, R>;
};
}, visitorKeys?: ASTVisitorKeyMap): R
Arguments
NameTypeDefaultDescription
rootASTNodeThe AST node where traversal starts.
visitor{
readonly [NodeT in ASTNode as NodeT[‘kind’]]?: {
readonly enter?: ASTVisitFn<NodeT>;
readonly leave: ASTReducerFn<NodeT, R>;
};
}
Reducer callbacks to invoke during traversal.
visitorKeys?ASTVisitorKeyMapQueryDocumentKeysOptional mapping of child keys for each AST node kind.
Returns
TypeDescription
RThe value produced by the reducer visitor.

visitInParallel()

Creates a new visitor instance which delegates to many visitors to run in parallel. Each visitor will be visited for each node before moving on.

If a prior visitor edits a node, no following visitors will see that node.

Signature:

visitInParallel(visitors: readonly ASTVisitor[]): ASTVisitor

Arguments

NameTypeDescription
visitorsreadonly ASTVisitor[]The visitors to merge into one parallel visitor.

Returns

TypeDescription
ASTVisitorA visitor that delegates traversal to each provided visitor.

Example

import { parse, visit, visitInParallel } from 'graphql/language';
 
const document = parse('{ hero { name } }');
const visited = visit(
  document,
  visitInParallel([{ Field() {} }, { Name() {} }]),
);
 
// Both visitors run during the same traversal.

getEnterLeaveForKind()

Given a visitor instance and a node kind, return EnterLeaveVisitor for that kind.

Signature:

getEnterLeaveForKind(visitor: ASTVisitor, kind: Kind): { enter?: ASTVisitFn<ASTNode>; leave?: ASTVisitFn<ASTNode> }

Arguments

NameTypeDescription
visitorASTVisitorThe visitor object to inspect.
kindKindThe AST node kind to resolve handlers for.

Returns

TypeDescription
{ enter?: ASTVisitFn<ASTNode>; leave?: ASTVisitFn<ASTNode> }The enter and leave handlers that apply for the given node kind.

Example

import { Kind, getEnterLeaveForKind } from 'graphql/language';
 
const handlers = getEnterLeaveForKind({ Field() {} }, Kind.FIELD);
 
// typeof handlers.enter === 'function'

getVisitFn()

Deprecated in v16

Given a visitor instance, if it is leaving or not, and a node kind, return the function the visitor runtime should call. This compatibility helper delegates to getEnterLeaveForKind; call getEnterLeaveForKind directly because getVisitFn will be removed in v17.

Signature:

getVisitFn(visitor: ASTVisitor, kind: Kind, isLeaving: boolean): ASTVisitFn<ASTNode> | undefined

Arguments

NameTypeDescription
visitorASTVisitorThe visitor object to inspect.
kindKindThe AST node kind to resolve a handler for.
isLeavingbooleanWhether to resolve the leave handler instead of the enter handler.

Returns

TypeDescription
ASTVisitFn<ASTNode> | undefinedThe visit function that applies for the given node kind and traversal phase, if one exists.

Example

import { Kind, getVisitFn } from 'graphql/language';
 
const enter = getVisitFn({ Field() {} }, Kind.FIELD, false);
 
// typeof enter === 'function'

Constants

BREAK

A value that can be returned from a visitor function to stop traversal.

unknown

Types

ASTVisitor

Type alias. A visitor is provided to visit, it contains the collection of relevant functions to be called during the visitor’s traversal.

type ASTVisitor = { enter?: ASTVisitFn<ASTNode>; leave?: ASTVisitFn<ASTNode> } | {
readonly [NodeT in ASTNode as NodeT[‘kind’]]?:
| ASTVisitFn<NodeT>
| EnterLeaveVisitor<NodeT>;
};

ASTVisitFn

Type alias. A visitor is comprised of visit functions, which are called on each node during the visitor’s traversal.

Type Parameters

NameConstraintDefaultDescription
TVisitedNodeASTNodeThe concrete AST node type passed to this visitor callback.
type ASTVisitFn<TVisitedNode extends ASTNode> = (node: TVisitedNode, key: string | number | undefined, parent: ASTNode | ReadonlyArray<ASTNode> | undefined, path: ReadonlyArray<string | number>, ancestors: ReadonlyArray<ASTNode | ReadonlyArray<ASTNode>>): any;

ASTVisitorKeyMap

Type alias. Deprecated in v16

Legacy visitor key map type retained for compatibility. Inline this mapped type at use sites; ASTVisitorKeyMap will be removed in v17.

type ASTVisitorKeyMap = mapped object;