Improve path.get typings with TS template literal types (#13588)
This commit is contained in:
parent
0a4b1b339c
commit
d45ad500e7
@ -320,6 +320,44 @@ export function getAllPrevSiblings(this: NodePath): NodePath[] {
|
||||
return siblings;
|
||||
}
|
||||
|
||||
// convert "1" to 1 (string index to number index)
|
||||
type MaybeToIndex<T extends string> = T extends `${bigint}` ? number : T;
|
||||
|
||||
type Pattern<Obj extends string, Prop extends string> = `${Obj}.${Prop}`;
|
||||
|
||||
// split "body.body.1" to ["body", "body", 1]
|
||||
type Split<P extends string> = P extends Pattern<infer O, infer U>
|
||||
? [MaybeToIndex<O>, ...Split<U>]
|
||||
: [MaybeToIndex<P>];
|
||||
|
||||
// get all K with Node[K] is t.Node | t.Node[]
|
||||
type NodeKeyOf<Node extends t.Node | t.Node[]> = keyof Pick<
|
||||
Node,
|
||||
{
|
||||
[Key in keyof Node]-?: Node[Key] extends t.Node | t.Node[] ? Key : never;
|
||||
}[keyof Node]
|
||||
>;
|
||||
|
||||
// traverse the Node with tuple path ["body", "body", 1]
|
||||
// Path should be created with Split
|
||||
type Trav<
|
||||
Node extends t.Node | t.Node[],
|
||||
Path extends unknown[],
|
||||
> = Path extends [infer K, ...infer R]
|
||||
? K extends NodeKeyOf<Node>
|
||||
? R extends []
|
||||
? Node[K]
|
||||
: // @ts-expect-error ignore since TS is not smart enough
|
||||
Trav<Node[K], R>
|
||||
: never
|
||||
: never;
|
||||
|
||||
type ToNodePath<T> = T extends Array<t.Node | null | undefined>
|
||||
? Array<NodePath<T[number]>>
|
||||
: T extends t.Node | null | undefined
|
||||
? NodePath<T>
|
||||
: never;
|
||||
|
||||
function get<T extends t.Node, K extends keyof T>(
|
||||
this: NodePath<T>,
|
||||
key: K,
|
||||
@ -330,6 +368,12 @@ function get<T extends t.Node, K extends keyof T>(
|
||||
? NodePath<T[K]>
|
||||
: never;
|
||||
|
||||
function get<T extends t.Node, K extends string>(
|
||||
this: NodePath<T>,
|
||||
key: K,
|
||||
context?: boolean | TraversalContext,
|
||||
): ToNodePath<Trav<T, Split<K>>>;
|
||||
|
||||
function get<T extends t.Node>(
|
||||
this: NodePath<T>,
|
||||
key: string,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user