1

I'm working on a crawler using Node.js. I use jQuery for parsing pages built using jsdom.

I found a jquery.d.ts through tsd, which ends like this:

declare module "jquery" {
    export = $;
}
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;

This definition seems to be usable only on client side where jQuery is loaded globally or where a global window variable is available...

As explained here, when imported (using require) in an environment where window.document is not available (like Node.js), jQuery export a factory of itself which has to be initalized with a window object:

// JavaScript (ES5)
var jquery = require("jquery");
// ...
var $ = jquery(window);

But with TypeScript, since the definition doesn't contain this factory. It doesn't work:

// TypeScript
import jquery from "jquery"; // Module '"jquery"' has no default export
import {jquery} from "jquery" // Module '"jquery"' has no exported member 'jquery'
import {jQuery} from "jquery" // Module '"jquery"' has no exported member 'jQuery'
import {$} from "jquery" // Module '"jquery"' has no exported member '$'
import * as jquery from "jquery"; // Doesn't complain here, but `jquery` variable is not usable

I tried to write a definition of this factory, but it seems to not be as simple as I tought:

interface JQueryFactory {
    (window: any): JQueryStatic;
}

declare module "jquery" {
    export default JQueryFactory;
}
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;

And use it:

// TypeScript
/// <reference path="../../typings/tsd.d.ts"/>

import jquery from "jquery";
// ...
var $ = jquery(window); // error TS2304: Cannot find name 'jquery'

But now I have this strange error ?!

2 Answers 2

3

I answer to my question:

I was very close, now, my jquery.d.ts ends like this:

declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;
declare function jQueryFactory (window: any): JQueryStatic;
declare module "jquery" {
    export default jQueryFactory;
}

I didn't succeed to achieve this without declare the jQueryFactory function.

As a small example, it can now basically be used like this :

import {env}  from "jsdom";
import jquery from "jquery";

interface StuffInterface
{
    title: string;
    text: string;
}

function parse (url: string): Promise<StuffInterface>
{
    return new Promise((resolve, reject) => {
        env(url, (e, window) => {
            if (e) {
                reject(e);
                return;
            }

            var $ = jquery(window);
            var stuff = {
                title: $('#stuff h1').text(),
                text: $('#stuff .content').text()
            };

            resolve(stuff);
        });
    });
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks for posting your own answer @Ascarius, could you please provide more detail on how you fixed it? I'm facing the same problems. Thanks!
@asheinfeld I added a basic example.
great, thanks @Ascarius! Maybe you should do a PR for jquery.d.ts so that everyone enjoys this, Cheers!
0

By TypeScript 1.8.9 without polluting jquery.d.ts

main.ts

require.config({
    baseUrl: '/js',
    shim: {
        jquery: {
            exports: '$' // Trick here!!!
        },
        underscore: {
            exports: '_' // Trick here!!!
        }
    },
    paths: {
        jquery: 'lib/jquery.min',
        underscore: 'lib/underscore.min'
    }
});

require(['foobar'], function (foobar) {
    foobar.runMe();
});

foobar.ts

import 'jquery';
import 'underscore';

export function runMe() {
    console.log($); // this print jquery object
    console.log(_); // this print underscore object
}

1 Comment

Off topic : The problem here concerns environments where window is not available, i such case, jquery export a factory, which is not corresponding with jquery.d.ts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.