11/**
2- * @typedef {import('unist').Node } Node
3- * @typedef {import('unist').Parent } Parent
4- * @typedef {import('unist-util-is').Test } Test
2+ * @typedef {import('unist').Node } UnistNode
3+ * @typedef {import('unist').Parent } UnistParent
4+ */
5+
6+ /**
7+ * @typedef {Exclude<import('unist-util-is').Test, undefined> | undefined } Test
8+ * Test from `unist-util-is`.
9+ *
10+ * Note: we have remove and add `undefined`, because otherwise when generating
11+ * automatic `.d.ts` files, TS tries to flatten paths from a local perspective,
12+ * which doesn’t work when publishing on npm.
13+ */
14+
15+ /**
16+ * @typedef {(
17+ * Fn extends (value: any) => value is infer Thing
18+ * ? Thing
19+ * : Fallback
20+ * )} Predicate
21+ * Get the value of a type guard `Fn`.
22+ * @template Fn
23+ * Value; typically function that is a type guard (such as `(x): x is Y`).
24+ * @template Fallback
25+ * Value to yield if `Fn` is not a type guard.
26+ */
27+
28+ /**
29+ * @typedef {(
30+ * Check extends null | undefined // No test.
31+ * ? Value
32+ * : Value extends {type: Check} // String (type) test.
33+ * ? Value
34+ * : Value extends Check // Partial test.
35+ * ? Value
36+ * : Check extends Function // Function test.
37+ * ? Predicate<Check, Value> extends Value
38+ * ? Predicate<Check, Value>
39+ * : never
40+ * : never // Some other test?
41+ * )} MatchesOne
42+ * Check whether a node matches a primitive check in the type system.
43+ * @template Value
44+ * Value; typically unist `Node`.
45+ * @template Check
46+ * Value; typically `unist-util-is`-compatible test, but not arrays.
47+ */
48+
49+ /**
50+ * @typedef {(
51+ * Check extends Array<any>
52+ * ? MatchesOne<Value, Check[keyof Check]>
53+ * : MatchesOne<Value, Check>
54+ * )} Matches
55+ * Check whether a node matches a check in the type system.
56+ * @template Value
57+ * Value; typically unist `Node`.
58+ * @template Check
59+ * Value; typically `unist-util-is`-compatible test.
60+ */
61+
62+ /**
63+ * @typedef {(
64+ * Kind extends {children: Array<infer Child>}
65+ * ? Child
66+ * : never
67+ * )} Child
68+ * Collect nodes that can be parents of `Child`.
69+ * @template {UnistNode} Kind
70+ * All node types.
571 */
672
773import { convert } from 'unist-util-is'
@@ -10,62 +76,63 @@ import {convert} from 'unist-util-is'
1076 * Find the nodes in `parent` before another `node` or before an index, that
1177 * pass `test`.
1278 *
13- * @template {Node} Kind
14- * Node type.
15- *
16- * @overload
17- * @param {Parent } parent
18- * @param {Node | number } index
19- * @param {import('unist-util-is').Test } test
20- * @returns {Array<Kind> }
21- *
22- * @overload
23- * @param {Parent } parent
24- * @param {Node | number } index
25- * @param {Test } [test]
26- * @returns {Array<Node> }
27- *
28- * @param {Parent } parent
79+ * @param parent
2980 * Parent node.
30- * @param { Node | number } index
31- * Child of `parent` or it’s index.
32- * @param { Test } [test]
33- * `unist-util-is`-compatible test .
34- * @returns { Array<Node> }
35- * Children of `parent` that pass `test` .
81+ * @param index
82+ * Child node or index.
83+ * @param [test=undefined ]
84+ * Test for child to look for (optional) .
85+ * @returns
86+ * Children (matching `test`, if given) .
3687 */
37- export function findAllBefore ( parent , index , test ) {
38- const is = convert ( test )
39- /** @type {Array<Node> } */
40- const results = [ ]
41- let offset = - 1
88+ export const findAllBefore =
89+ // Note: overloads like this are needed to support optional generics.
90+ /**
91+ * @type {(
92+ * (<Kind extends UnistParent, Check extends Test>(parent: Kind, index: Child<Kind> | number, test: Check) => Array<Matches<Child<Kind>, Check>>) &
93+ * (<Kind extends UnistParent>(parent: Kind, index: Child<Kind> | number, test?: null | undefined) => Array<Child<Kind>>)
94+ * )}
95+ */
96+ (
97+ /**
98+ * @param {UnistParent } parent
99+ * @param {UnistNode | number } index
100+ * @param {Test } [test]
101+ * @returns {Array<UnistNode> }
102+ */
103+ function ( parent , index , test ) {
104+ const is = convert ( test )
105+ /** @type {Array<UnistNode> } */
106+ const results = [ ]
107+ let offset = - 1
42108
43- if ( ! parent || ! parent . type || ! parent . children ) {
44- throw new Error ( 'Expected parent node' )
45- }
109+ if ( ! parent || ! parent . type || ! parent . children ) {
110+ throw new Error ( 'Expected parent node' )
111+ }
46112
47- if ( typeof index === 'number' ) {
48- if ( index < 0 || index === Number . POSITIVE_INFINITY ) {
49- throw new Error ( 'Expected positive finite number as index' )
50- }
51- } else {
52- index = parent . children . indexOf ( index )
113+ if ( typeof index === 'number' ) {
114+ if ( index < 0 || index === Number . POSITIVE_INFINITY ) {
115+ throw new Error ( 'Expected positive finite number as index' )
116+ }
117+ } else {
118+ index = parent . children . indexOf ( index )
53119
54- if ( index < 0 ) {
55- throw new Error ( 'Expected child node or index' )
56- }
57- }
120+ if ( index < 0 ) {
121+ throw new Error ( 'Expected child node or index' )
122+ }
123+ }
58124
59- // Performance.
60- if ( index > parent . children . length ) {
61- index = parent . children . length
62- }
125+ // Performance.
126+ if ( index > parent . children . length ) {
127+ index = parent . children . length
128+ }
63129
64- while ( ++ offset < index ) {
65- if ( is ( parent . children [ offset ] , offset , parent ) ) {
66- results . push ( parent . children [ offset ] )
67- }
68- }
130+ while ( ++ offset < index ) {
131+ if ( is ( parent . children [ offset ] , offset , parent ) ) {
132+ results . push ( parent . children [ offset ] )
133+ }
134+ }
69135
70- return results
71- }
136+ return results
137+ }
138+ )
0 commit comments