Skip to content

Commit 5866920

Browse files
authored
refactor(traverse): widen TypeScript type for visitors (#13)
1 parent dcd069b commit 5866920

File tree

11 files changed

+41
-77
lines changed

11 files changed

+41
-77
lines changed

packages/apidom-reference/src/dereference/strategies/apidom/visitor.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,6 @@ class ApiDOMDereferenceVisitor {
207207
path.replaceWith(referencedElement);
208208
}
209209
}
210-
211-
// Index signature for Visitor compatibility
212-
[key: string]: unknown;
213210
}
214211

215212
export default ApiDOMDereferenceVisitor;

packages/apidom-reference/src/dereference/strategies/asyncapi-2/visitor.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,6 @@ class AsyncAPI2DereferenceVisitor {
490490
*/
491491
path.replaceWith(referencedElement);
492492
}
493-
494-
// Index signature for Visitor compatibility
495-
[key: string]: unknown;
496493
}
497494

498495
export default AsyncAPI2DereferenceVisitor;

packages/apidom-reference/src/dereference/strategies/openapi-2/visitor.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,6 @@ class OpenAPI2DereferenceVisitor {
633633
path.replaceWith(mergedElement);
634634
return;
635635
}
636-
637-
// Index signature for Visitor compatibility
638-
[key: string]: unknown;
639636
}
640637

641638
export default OpenAPI2DereferenceVisitor;

packages/apidom-reference/src/dereference/strategies/openapi-3-0/visitor.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,6 @@ class OpenAPI3_0DereferenceVisitor {
609609
*/
610610
path.replaceWith(exampleElementCopy);
611611
}
612-
613-
// Index signature for Visitor compatibility
614-
[key: string]: unknown;
615612
}
616613

617614
export default OpenAPI3_0DereferenceVisitor;

packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -904,9 +904,6 @@ class OpenAPI3_1DereferenceVisitor {
904904
*/
905905
path.replaceWith(referencedElement);
906906
}
907-
908-
// Index signature for Visitor compatibility
909-
[key: string]: unknown;
910907
}
911908

912909
export default OpenAPI3_1DereferenceVisitor;

packages/apidom-traverse/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export {
2525
} from './visitors.ts';
2626
export type {
2727
NodeVisitor,
28-
Visitor,
2928
MergeVisitorsOptions,
3029
MergedVisitor,
3130
MergedVisitorAsync,

packages/apidom-traverse/src/traversal.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { isPromise } from 'ramda-adjunct';
1010
import { Path } from './Path.ts';
1111
import type { VisitorFn, VisitorResult } from './Path.ts';
1212
import { getNodeType, isNode, cloneNode, mutateNode, getVisitFn, getNodeKeys } from './visitors.ts';
13-
import type { Visitor } from './visitors.ts';
1413

1514
/**
1615
* Options for the traverse function.
@@ -79,7 +78,7 @@ interface TraversalState<TNode> {
7978

8079
function* traverseGenerator<TNode>(
8180
root: TNode,
82-
visitor: Visitor<TNode>,
81+
visitor: object,
8382
options: Required<TraverseOptions<TNode>>,
8483
): Generator<VisitorCall<TNode>, TNode, VisitorResult<TNode>> {
8584
const {
@@ -175,7 +174,7 @@ function* traverseGenerator<TNode>(
175174
// Always create Path for the current node (needed for parentPath chain)
176175
currentPath = new Path<TNode>(node, parent, parentPath, key, inArray);
177176

178-
const visitFn = getVisitFn(visitor, nodeTypeGetter(node), isLeaving);
177+
const visitFn = getVisitFn<TNode>(visitor, nodeTypeGetter(node), isLeaving);
179178

180179
if (visitFn) {
181180
// Assign state to visitor
@@ -310,7 +309,7 @@ function* traverseGenerator<TNode>(
310309
*/
311310
export const traverse = <TNode>(
312311
root: TNode,
313-
visitor: Visitor<TNode>,
312+
visitor: object,
314313
options: TraverseOptions<TNode> = {},
315314
): TNode => {
316315
const resolvedOptions: Required<TraverseOptions<TNode>> = {
@@ -350,7 +349,7 @@ export const traverse = <TNode>(
350349
*/
351350
export const traverseAsync = async <TNode>(
352351
root: TNode,
353-
visitor: Visitor<TNode>,
352+
visitor: object,
354353
options: TraverseOptions<TNode> = {},
355354
): Promise<TNode> => {
356355
const resolvedOptions: Required<TraverseOptions<TNode>> = {

packages/apidom-traverse/src/visitors.ts

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { isPromise } from 'ramda-adjunct';
1111

1212
import { Path } from './Path.ts';
13-
import type { VisitorFn } from './Path.ts';
13+
import type { VisitorFn, VisitorResult } from './Path.ts';
1414

1515
/**
1616
* Enter/leave visitor structure for a specific node type.
@@ -21,23 +21,6 @@ export interface NodeVisitor<TNode, TVisitor = unknown> {
2121
leave?: VisitorFn<TNode, TVisitor>;
2222
}
2323

24-
/**
25-
* Visitor object structure.
26-
* Visitors can have:
27-
* - `enter`/`leave` for generic callbacks
28-
* - Type-specific methods like `StringElement(path) {}`
29-
* - Type-specific enter/leave like `StringElement: { enter, leave }`
30-
* - Any other properties (for class-based visitors)
31-
*
32-
* Note: Class-based visitors must add `[key: string]: unknown;` index signature.
33-
* @public
34-
*/
35-
export type Visitor<TNode> = {
36-
enter?: VisitorFn<TNode> | Record<string, VisitorFn<TNode>>;
37-
leave?: VisitorFn<TNode> | Record<string, VisitorFn<TNode>>;
38-
[key: string]: unknown;
39-
};
40-
4124
// =============================================================================
4225
// Default implementations for ApiDOM
4326
// =============================================================================
@@ -154,7 +137,7 @@ const lookup = (record: Record<string, unknown>, type: string): unknown => {
154137
* @public
155138
*/
156139
export const getVisitFn = <TNode>(
157-
visitor: Visitor<TNode>,
140+
visitor: object,
158141
type: string | undefined,
159142
isLeaving: boolean,
160143
): VisitorFn<TNode> | null => {
@@ -237,7 +220,7 @@ export interface MergedVisitorAsync<TNode> {
237220
* @public
238221
*/
239222
export const mergeVisitors = <TNode>(
240-
visitors: Visitor<TNode>[],
223+
visitors: object[],
241224
options: MergeVisitorsOptions<TNode> = {},
242225
): MergedVisitor<TNode> => {
243226
const {
@@ -253,13 +236,13 @@ export const mergeVisitors = <TNode>(
253236
const skipping: (symbol | TNode)[] = new Array(visitors.length).fill(internalSkipSymbol);
254237

255238
return {
256-
enter(path: Path<TNode>) {
239+
enter(path: Path<TNode>): VisitorResult<TNode> {
257240
let currentNode = path.node;
258241
let hasChanged = false;
259242

260243
for (let i = 0; i < visitors.length; i += 1) {
261244
if (skipping[i] === internalSkipSymbol) {
262-
const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), false);
245+
const visitFn = visitFnGetter<TNode>(visitors[i], nodeTypeGetter(currentNode), false);
263246

264247
if (typeof visitFn === 'function') {
265248
// Create a proxy path that tracks changes per-visitor
@@ -320,12 +303,12 @@ export const mergeVisitors = <TNode>(
320303
return undefined;
321304
},
322305

323-
leave(path: Path<TNode>) {
306+
leave(path: Path<TNode>): VisitorResult<TNode> {
324307
const currentNode = path.node;
325308

326309
for (let i = 0; i < visitors.length; i += 1) {
327310
if (skipping[i] === internalSkipSymbol) {
328-
const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), true);
311+
const visitFn = visitFnGetter<TNode>(visitors[i], nodeTypeGetter(currentNode), true);
329312

330313
if (typeof visitFn === 'function') {
331314
// Create a proxy path for leave phase
@@ -376,7 +359,7 @@ export const mergeVisitors = <TNode>(
376359
* @public
377360
*/
378361
export const mergeVisitorsAsync = <TNode>(
379-
visitors: Visitor<TNode>[],
362+
visitors: object[],
380363
options: MergeVisitorsOptions<TNode> = {},
381364
): MergedVisitorAsync<TNode> => {
382365
const {
@@ -390,13 +373,13 @@ export const mergeVisitorsAsync = <TNode>(
390373
const skipping: (symbol | TNode)[] = new Array(visitors.length).fill(internalSkipSymbol);
391374

392375
return {
393-
async enter(path: Path<TNode>) {
376+
async enter(path: Path<TNode>): Promise<void | TNode | undefined> {
394377
let currentNode = path.node;
395378
let hasChanged = false;
396379

397380
for (let i = 0; i < visitors.length; i += 1) {
398381
if (skipping[i] === internalSkipSymbol) {
399-
const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), false);
382+
const visitFn = visitFnGetter<TNode>(visitors[i], nodeTypeGetter(currentNode), false);
400383

401384
if (typeof visitFn === 'function') {
402385
const proxyPath = createPathProxy(path, currentNode);
@@ -446,12 +429,12 @@ export const mergeVisitorsAsync = <TNode>(
446429
return undefined;
447430
},
448431

449-
async leave(path: Path<TNode>) {
432+
async leave(path: Path<TNode>): Promise<void | TNode | undefined> {
450433
const currentNode = path.node;
451434

452435
for (let i = 0; i < visitors.length; i += 1) {
453436
if (skipping[i] === internalSkipSymbol) {
454-
const visitFn = visitFnGetter(visitors[i], nodeTypeGetter(currentNode), true);
437+
const visitFn = visitFnGetter<TNode>(visitors[i], nodeTypeGetter(currentNode), true);
455438

456439
if (typeof visitFn === 'function') {
457440
const proxyPath = createPathProxy(path, currentNode);

0 commit comments

Comments
 (0)