Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you add methods when using typescript? #1778

Closed
mikestopcontinues opened this issue Mar 15, 2021 · 7 comments · Fixed by #1915
Closed

How do you add methods when using typescript? #1778

mikestopcontinues opened this issue Mar 15, 2021 · 7 comments · Fixed by #1915

Comments

@mikestopcontinues
Copy link

I believe I might have found an issue with how cheerio exports types, but I'm new to typescript, so I'm not sure I'm not just missing how to get it done.

I'm running v1.0.0-rc.5, and I'd like to be able to add some methods to the Cheerio interface, so that when I run a selector query, I get back the full api (both mine and the core methods). I had better luck using @types/cheerio, as it seemed to expose more of the API, but I wasn't able to get it fully working there either. For that reason, I'm not sure #1682 is going to fully solve the problem.

I'd like to be able to include a code sample, but working against v1, nothing I came up with is close. If it is possible with the current release, I'd just like to know how to do it. Thanks!

@fb55
Copy link
Member

fb55 commented Mar 15, 2021

#1407 should be helpful here!

@fb55 fb55 closed this as completed Mar 15, 2021
@mikestopcontinues
Copy link
Author

Hi, this issue should be re-opened. I don't know how #1407 got it working. Perhaps he was using @types/cheerio? Merging doesn't work on any level (global, module, namespace). Any attempt just overrides the base interfaces. I can't be sure, but I suspect the issue is that the interfaces aren't being exported. In the examples here, they are exporting everything they merge.

@fb55 fb55 reopened this Mar 16, 2021
@ThePawlow
Copy link

ThePawlow commented Apr 8, 2021

How can I get this to work?

Types are installed (@types/cheerio).
I can't specifiy types, and the importing is behaving weird.

Typescript 3.8.3
@types/cheerio 0.22.28
cheerio 1.0.0-rc.5

@greg-murray-volusion
Copy link

It compiled for me when uninstalling the @types/cheerio. I'm running with cheerio@1.0.0-rc.6 and typescript/@3.8.3

@n1xx1
Copy link
Contributor

n1xx1 commented Jun 5, 2021

Hello, this is what I'm using with 1.0.0-rc.9

import { Cheerio, CheerioAPI, FilterFunction, Node } from "cheerio";
import { domEach } from "cheerio/lib/utils";

type AcceptedFiltersGeneric<T extends Node> =
    | string
    | FilterFunction<T>
    | T
    | Cheerio<T>;

declare module "cheerio" {
    namespace Custom {
        function nextNode<T extends Node>(
            this: Cheerio<T>,
            selector?: AcceptedFiltersGeneric<T>,
        ): Cheerio<Node>;
    }
    type CustomTypes = typeof Custom;

    interface Cheerio<T> extends CustomTypes {}
}

export function initPlugin($: CheerioAPI) {
    $.prototype.nextNode = function <T extends Node>(
        this: Cheerio<T>,
        selector?: AcceptedFiltersGeneric<T>,
    ): Cheerio<Node> {
        const elems: Node[] = [];
        for (const e of this) {
            if (e.next) {
                elems.push(e.next);
            }
        }
        return selector
            ? this.filter.call(elems, selector, this)
            : this._make(elems);
    };
}

Defining the method inside the interface was giving me problems when calling functions that accept Cheerio<Node> with Cheerio<Element>, so I switched to this namespace approach. Another cool thing about this is that you only need a single file that will contain both the implementation and the definition.

fb55 added a commit that referenced this issue Jun 7, 2021
As proposed by @n1xx1 in #1778 (comment)

Co-Authored-By: n1xx1 <680445+n1xx1@users.noreply.github.com>
@fb55
Copy link
Member

fb55 commented Jun 7, 2021

Thanks for the response @n1xx1! I have opened #1915 that documents this pattern & uses it in Cheerio's unit tests.

@fb55 fb55 closed this as completed in #1915 Jun 7, 2021
fb55 added a commit that referenced this issue Jun 7, 2021
As proposed by @n1xx1 in #1778 (comment)

Co-authored-by: n1xx1 <680445+n1xx1@users.noreply.github.com>
@mikestopcontinues
Copy link
Author

Just want to add, you need to include export {} (or export anything) in your .d.ts file for the new method to work. Otherwise the custom definition overrides the basic export types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants