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 ?!

4

2 回答 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);
        });
    });
}
于 2015-11-13T18:20:43.190 回答
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
}
于 2016-03-21T17:51:26.410 回答