Installing @types/jquery results in an unwanted global $ declaration

Viewed 142

I have the following defined in package.json:

{
  "dependencies": {
    "@types/jquery": "^3.5.5",
  }
}

Which adds the following type declaration via @types/jquery/misc.d.ts:

declare const jQuery: JQueryStatic;
declare const $: JQueryStatic;

Now I have global $ and jQuery variables defined for all of my modules, but this is not only unwanted... it's wrong. Code similar to the following is blowing up at runtime because the TypeScript compiler believes that $ is a global when in fact it must be imported:

// $ is never imported here, and jQuery is not initialized globally in the browser

export function foo(node?:JQueryXML):void {
    node.children().each(function(_, el) {
        let node = $(el);
        if (node.attr("type") === VALUE) {
            doStuff();
        }
    });
}

Just to be sure, I tried commenting out those two declaration lines in @types/jquery/misc.d.ts and I got the expected error:

error TS2592: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig.

40    let node = $(el);

However, I've now effectively disabled all jQuery type checking. I've got an additional 50+ errors because all other modules where I correctly import $ are treating the variable as any.

How can I tell the TypeScript compiler that I want the type definitions from @types/jquery but that $ is not a valid global variable?

1 Answers

You can explicitly tell TypeScript the types to search in the compiler options: https://www.typescriptlang.org/tsconfig#types

From the docs:

By default all visible ”@types” packages are included in your compilation. Packages in node_modules/@types of any enclosing folder are considered visible. For example, that means packages within ./node_modules/@types/, ../node_modules/@types/, ../../node_modules/@types/, and so on.

If types is specified, only packages listed will be included in the global scope.

In this case the compiler is automatically including the global type from node_modules/@types/jquery.

Related