@@ -44,7 +44,7 @@ export function find<T extends Node>(
44
44
45
45
if ( typeof selectorOrHaystack !== 'string' ) {
46
46
const haystack = isCheerio ( selectorOrHaystack )
47
- ? selectorOrHaystack . get ( )
47
+ ? selectorOrHaystack . toArray ( )
48
48
: [ selectorOrHaystack ] ;
49
49
50
50
return this . _make (
@@ -85,7 +85,7 @@ export function find<T extends Node>(
85
85
*/
86
86
export function parent < T extends Node > (
87
87
this : Cheerio < T > ,
88
- selector ?: AcceptedFilters
88
+ selector ?: AcceptedFilters < T >
89
89
) : Cheerio < Element > {
90
90
const set : Element [ ] = [ ] ;
91
91
@@ -123,7 +123,7 @@ export function parent<T extends Node>(
123
123
*/
124
124
export function parents < T extends Node > (
125
125
this : Cheerio < T > ,
126
- selector ?: AcceptedFilters
126
+ selector ?: AcceptedFilters < T >
127
127
) : Cheerio < Element > {
128
128
const parentNodes : Element [ ] = [ ] ;
129
129
@@ -166,7 +166,7 @@ export function parents<T extends Node>(
166
166
export function parentsUntil < T extends Node > (
167
167
this : Cheerio < T > ,
168
168
selector ?: string | Node | Cheerio < Node > ,
169
- filterBy ?: AcceptedFilters
169
+ filterBy ?: AcceptedFilters < T >
170
170
) : Cheerio < Element > {
171
171
const parentNodes : Element [ ] = [ ] ;
172
172
let untilNode : Node | undefined ;
@@ -237,7 +237,7 @@ export function parentsUntil<T extends Node>(
237
237
*/
238
238
export function closest < T extends Node > (
239
239
this : Cheerio < T > ,
240
- selector ?: AcceptedFilters
240
+ selector ?: AcceptedFilters < T >
241
241
) : Cheerio < Node > {
242
242
const set : Node [ ] = [ ] ;
243
243
@@ -274,7 +274,7 @@ export function closest<T extends Node>(
274
274
*/
275
275
export function next < T extends Node > (
276
276
this : Cheerio < T > ,
277
- selector ?: AcceptedFilters
277
+ selector ?: AcceptedFilters < T >
278
278
) : Cheerio < Element > {
279
279
const elems : Element [ ] = [ ] ;
280
280
@@ -311,7 +311,7 @@ export function next<T extends Node>(
311
311
*/
312
312
export function nextAll < T extends Node > (
313
313
this : Cheerio < T > ,
314
- selector ?: AcceptedFilters
314
+ selector ?: AcceptedFilters < T >
315
315
) : Cheerio < Element > {
316
316
const elems : Element [ ] = [ ] ;
317
317
@@ -347,7 +347,7 @@ export function nextAll<T extends Node>(
347
347
export function nextUntil < T extends Node > (
348
348
this : Cheerio < T > ,
349
349
selector ?: string | Cheerio < Node > | Node | null ,
350
- filterSelector ?: AcceptedFilters
350
+ filterSelector ?: AcceptedFilters < T >
351
351
) : Cheerio < Element > {
352
352
const elems : Element [ ] = [ ] ;
353
353
let untilNode : Node | undefined ;
@@ -401,7 +401,7 @@ export function nextUntil<T extends Node>(
401
401
*/
402
402
export function prev < T extends Node > (
403
403
this : Cheerio < T > ,
404
- selector ?: AcceptedFilters
404
+ selector ?: AcceptedFilters < T >
405
405
) : Cheerio < Element > {
406
406
const elems : Element [ ] = [ ] ;
407
407
@@ -439,7 +439,7 @@ export function prev<T extends Node>(
439
439
*/
440
440
export function prevAll < T extends Node > (
441
441
this : Cheerio < T > ,
442
- selector ?: AcceptedFilters
442
+ selector ?: AcceptedFilters < T >
443
443
) : Cheerio < Element > {
444
444
const elems : Element [ ] = [ ] ;
445
445
@@ -475,7 +475,7 @@ export function prevAll<T extends Node>(
475
475
export function prevUntil < T extends Node > (
476
476
this : Cheerio < T > ,
477
477
selector ?: string | Cheerio < Node > | Node | null ,
478
- filterSelector ?: AcceptedFilters
478
+ filterSelector ?: AcceptedFilters < T >
479
479
) : Cheerio < Element > {
480
480
const elems : Element [ ] = [ ] ;
481
481
let untilNode : Node | undefined ;
@@ -532,7 +532,7 @@ export function prevUntil<T extends Node>(
532
532
*/
533
533
export function siblings < T extends Node > (
534
534
this : Cheerio < T > ,
535
- selector ?: AcceptedFilters
535
+ selector ?: AcceptedFilters < T >
536
536
) : Cheerio < Element > {
537
537
// TODO Still get siblings if `parent` is null; see DomUtils' `getSiblings`.
538
538
const parent = this . parent ( ) ;
@@ -566,7 +566,7 @@ export function siblings<T extends Node>(
566
566
*/
567
567
export function children < T extends Node > (
568
568
this : Cheerio < T > ,
569
- selector ?: AcceptedFilters
569
+ selector ?: AcceptedFilters < T >
570
570
) : Cheerio < Element > {
571
571
const elems = this . toArray ( ) . reduce < Element [ ] > (
572
572
( newElems , elem ) =>
@@ -679,16 +679,16 @@ export function map<T, M>(
679
679
return this . _make ( elems ) ;
680
680
}
681
681
682
- function getFilterFn < T extends Node , S extends T > (
683
- match : ( ( this : S , i : number , el : S ) => boolean ) | Cheerio < T > | T
684
- ) : ( el : S , i : number ) => boolean {
682
+ function getFilterFn < T > (
683
+ match : FilterFunction < T > | Cheerio < T > | T
684
+ ) : ( el : T , i : number ) => boolean {
685
685
if ( typeof match === 'function' ) {
686
686
return function ( el , i ) {
687
- return match . call ( el , i , el ) ;
687
+ return ( match as FilterFunction < T > ) . call ( el , i , el ) ;
688
688
} ;
689
689
}
690
- if ( isCheerio ( match ) ) {
691
- return match . is . bind ( match ) ;
690
+ if ( isCheerio < T > ( match ) ) {
691
+ return ( el ) => match . is ( el ) ;
692
692
}
693
693
return function ( el ) {
694
694
return match === el ;
@@ -697,12 +697,42 @@ function getFilterFn<T extends Node, S extends T>(
697
697
698
698
/**
699
699
* Iterates over a cheerio object, reducing the set of selector elements to
700
- * those that match the selector or pass the function's test. When a Cheerio
701
- * selection is specified, return only the elements contained in that selection.
702
- * When an element is specified, return only that element (if it is contained in
703
- * the original selection). If using the function method, the function is
704
- * executed in the context of the selected element, so `this` refers to the
705
- * current element.
700
+ * those that match the selector or pass the function's test.
701
+ *
702
+ * This is the definition for using type guards; have a look below for other
703
+ * ways to invoke this method. The function is executed in the context of the
704
+ * selected element, so `this` refers to the current element.
705
+ *
706
+ * @category Traversing
707
+ * @example <caption>Function</caption>
708
+ *
709
+ * ```js
710
+ * $('li')
711
+ * .filter(function (i, el) {
712
+ * // this === el
713
+ * return $(this).attr('class') === 'orange';
714
+ * })
715
+ * .attr('class'); //=> orange
716
+ * ```
717
+ *
718
+ * @param match - Value to look for, following the rules above.
719
+ * @returns The filtered collection.
720
+ * @see {@link https://api.jquery.com/filter/ }
721
+ */
722
+ export function filter < T , S extends T > (
723
+ this : Cheerio < T > ,
724
+ match : ( this : T , index : number , value : T ) => value is S
725
+ ) : Cheerio < S > ;
726
+ /**
727
+ * Iterates over a cheerio object, reducing the set of selector elements to
728
+ * those that match the selector or pass the function's test.
729
+ *
730
+ * - When a Cheerio selection is specified, return only the elements contained in
731
+ * that selection.
732
+ * - When an element is specified, return only that element (if it is contained in
733
+ * the original selection).
734
+ * - If using the function method, the function is executed in the context of the
735
+ * selected element, so `this` refers to the current element.
706
736
*
707
737
* @category Traversing
708
738
* @example <caption>Selector</caption>
@@ -723,29 +753,50 @@ function getFilterFn<T extends Node, S extends T>(
723
753
* .attr('class'); //=> orange
724
754
* ```
725
755
*
756
+ * @param match - Value to look for, following the rules above. See
757
+ * {@link AcceptedFilters}.
758
+ * @returns The filtered collection.
759
+ * @see {@link https://api.jquery.com/filter/ }
760
+ */
761
+ export function filter < T , S extends AcceptedFilters < T > > (
762
+ this : Cheerio < T > ,
763
+ match : S
764
+ ) : Cheerio < S extends string ? Element : T > ;
765
+ /**
766
+ * Internal `filter` variant used by other functions to filter their elements.
767
+ *
768
+ * @private
726
769
* @param match - Value to look for, following the rules above.
727
- * @param container - Optional node to filter instead .
770
+ * @param container - The container that is used to create the resulting Cheerio instance .
728
771
* @returns The filtered collection.
729
772
* @see {@link https://api.jquery.com/filter/ }
730
773
*/
731
- export function filter (
732
- this : Cheerio < Node > | Node [ ] ,
733
- match : AcceptedFilters ,
774
+ export function filter < T > (
775
+ this : T [ ] ,
776
+ match : AcceptedFilters < T > ,
777
+ container : Cheerio < Node >
778
+ ) : Cheerio < Element > ;
779
+ export function filter < T > (
780
+ this : Cheerio < T > | T [ ] ,
781
+ match : AcceptedFilters < T > ,
734
782
container = this
735
- ) : Cheerio < Element > {
783
+ ) : Cheerio < unknown > {
736
784
if ( ! isCheerio ( container ) ) {
737
785
throw new Error ( 'Not able to create a Cheerio instance.' ) ;
738
786
}
739
787
740
788
const nodes = isCheerio ( this ) ? this . toArray ( ) : this ;
741
- let elements : Element [ ] = nodes . filter ( isTag ) ;
742
789
743
- elements =
790
+ const result =
744
791
typeof match === 'string'
745
- ? select . filter ( match , elements , container . options )
746
- : elements . filter ( getFilterFn ( match ) ) ;
747
-
748
- return container . _make ( elements ) ;
792
+ ? select . filter (
793
+ match ,
794
+ ( ( nodes as unknown ) as Node [ ] ) . filter ( isTag ) ,
795
+ container . options
796
+ )
797
+ : nodes . filter ( getFilterFn ( match ) ) ;
798
+
799
+ return container . _make < unknown > ( result ) ;
749
800
}
750
801
751
802
/**
@@ -783,7 +834,7 @@ export function filter(
783
834
*/
784
835
export function not < T extends Node > (
785
836
this : Cheerio < T > | T [ ] ,
786
- match : Node | Cheerio < Node > | string | FilterFunction < T > ,
837
+ match : AcceptedFilters < T > ,
787
838
container = this
788
839
) : Cheerio < T > {
789
840
if ( ! isCheerio ( container ) ) {
@@ -834,8 +885,7 @@ export function has(
834
885
this : Cheerio < Node | Element > ,
835
886
selectorOrHaystack : string | Cheerio < Element > | Element
836
887
) : Cheerio < Node | Element > {
837
- return filter . call (
838
- this ,
888
+ return this . filter (
839
889
typeof selectorOrHaystack === 'string'
840
890
? // Using the `:has` selector here short-circuits searches.
841
891
`:has(${ selectorOrHaystack } )`
@@ -1036,7 +1086,7 @@ export function slice<T>(
1036
1086
function traverseParents < T extends Node > (
1037
1087
self : Cheerio < T > ,
1038
1088
elem : Node | null ,
1039
- selector : AcceptedFilters | undefined ,
1089
+ selector : AcceptedFilters < T > | undefined ,
1040
1090
limit : number
1041
1091
) : Node [ ] {
1042
1092
const elems : Node [ ] = [ ] ;
0 commit comments