Skip to content

Typescript error "ts(4023)" caused by index.d.ts #1692

@rondonjon

Description

@rondonjon

I am getting TypeScript error ts(4023) in my application when I try to use any of the types in the cheerio namespace as return types.

import { load } from "cheerio";
export const parseHtml = async (source: string | Buffer) => load(source);
Exported variable 'parseHtml' has or is using name 'cheerio.Root' from external module "/.../node_modules/cheerio/types/index" but cannot be named.

The compiler can't use cheerio.Root as return type because Root is in the cheerio namespace and that namespace is currently not exported.

I've already spent a few hours finding a possible fix, here is what I found so far:

Approach no. 1 - preserving the namespace (currently not working)

A common pattern which is used by @types/React and many others is to export both, API and namespace.

export = React;
export as namespace React;

But this only seems to work if all API functions are direct members of the namespace:

declare namespace cheerio {
  function load(...)
}

This is currently not the case. It seems that the API definition is currently distributed over three abstract interfaces (Selector, Root, and CheerioAPI) inside the namespace, whereas the actual API instance (which is then exported as default) resides outside the namespace.

While the members of two of these interfaces, Root and CheerioAPI, could actually be unwrapped very easily, ...

  //interface CheerioAPI extends Root {
    const version: string;
    function load(html: string | { toString(): string }, options?: CheerioParserOptions): Root;
    function load(element: Element, options?: CheerioParserOptions): Root;
  //}

... I am still struggling with the third, Selector, which describes the signature of the default export when it is used as a function:

interface Selector {
    (selector: string): Cheerio;
    (selector: string, context: string): Cheerio;

As much as I like the namespace idea, for me, with rather limited Typescript experience, this is a dead end.

Approach no. 2 - without the namespace (working)

So I tried something completely different, removed the cheerio namespace altogether and marked all its members as direct exports. While this is clearly not the "prettiest" solution, it is at least a "working" solution; the TypeScript error has disappeared.

Merge Request???

For this latter solution, I could contribute a MR if desired.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions