Skip to content

Commit a645f15

Browse files
authored
🤖 Merge PR DefinitelyTyped#72228 [@babel/traverse]: Add support for recursive NodePath::get(…) calls by @ExE-Boss
1 parent 4e0c691 commit a645f15

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

‎types/babel__traverse/babel__traverse-tests.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const MyVisitor2: Visitor = {
2525
},
2626
ArrayExpression(path) {
2727
path.get("elements"); // $ExpectType NodePath<SpreadElement | Expression | null>[]
28+
path.get("elements.0"); // $ExpectType NodePath<SpreadElement | Expression | null>
2829
},
2930
Program(path) {
3031
path.parentPath; // $ExpectType null
@@ -374,6 +375,7 @@ const objectTypeAnnotation: NodePath<t.ObjectTypeAnnotation> = new NodePath<t.Ob
374375
);
375376

376377
objectTypeAnnotation.get("indexers"); // $ExpectType NodePathResult<ObjectTypeIndexer[] | undefined>
378+
objectTypeAnnotation.get("indexers.0"); // $ExpectType NodePath<ObjectTypeIndexer>
377379

378380
// Test that NodePath can be narrowed from union to single type
379381
const path: NodePath<t.ExportDefaultDeclaration | t.ExportNamedDeclaration> = new NodePath<t.ExportNamedDeclaration>(
@@ -427,7 +429,9 @@ binding.deopValue();
427429
binding.clearValue();
428430

429431
binding.reassign(newPath.get("body")[0]);
432+
binding.reassign(newPath.get("body.0"));
430433
binding.reference(newPath.get("body")[0]);
434+
binding.reference(newPath.get("body.0"));
431435
binding.dereference();
432436

433437
newPath.scope.checkBlockScopedCollisions(binding, "local", "name", {});

‎types/babel__traverse/index.d.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ export class NodePath<T = Node> {
746746
getAllNextSiblings(): NodePath[];
747747

748748
get<K extends keyof T>(key: K, context?: boolean | TraversalContext): NodePathResult<T[K]>;
749+
get<P extends string>(path: P, context?: boolean | TraversalContext): NodePathResult<ImplGetRecursive<T, P>>;
749750
get(key: string, context?: boolean | TraversalContext): NodePath | NodePath[];
750751

751752
getBindingIdentifiers(duplicates: true): Record<string, t.Identifier[]>;
@@ -1448,6 +1449,27 @@ export interface TraversalContext<S = unknown> {
14481449
opts: TraverseOptions;
14491450
}
14501451

1452+
// Based on `GetFieldType`s from `@types/lodash/common/object.d.ts`:
1453+
// dprint-ignore
1454+
type ImplGetOfArray<T extends readonly unknown[], K extends string> =
1455+
K extends `${infer N extends number}` ? T[N]
1456+
: K extends keyof T ? T[K]
1457+
: never;
1458+
1459+
// dprint-ignore
1460+
type ImplGetByKey<T, K extends string>
1461+
= T extends readonly unknown[] ? ImplGetOfArray<T, K>
1462+
: K extends keyof T ? T[K]
1463+
: K extends `${infer N extends number}`
1464+
? N extends keyof T ? T[N] : never
1465+
: never;
1466+
1467+
// dprint-ignore
1468+
type ImplGetRecursive<T, K extends string>
1469+
= K extends `${infer L}.${infer R}`
1470+
? ImplGetRecursive<ImplGetByKey<T, L>, R>
1471+
: ImplGetByKey<T, K>;
1472+
14511473
export type NodePathResult<T> =
14521474
| (Extract<T, Node | null | undefined> extends never ? never : NodePath<Extract<T, Node | null | undefined>>)
14531475
| (T extends Array<Node | null | undefined> ? Array<NodePath<T[number]>> : never);

0 commit comments

Comments
 (0)