-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
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.