2

I can load jQuery using amd modules like this - require jquery via AMD in TypeScript I also understand how plugins can modify the jquery interface without modules - Using jQuery plugin in TypeScript

But how do I load a jQuery plugin via AMD modules? And have it update the jQuery interface?

import plugin1 = module("jquery.tmpl");
import jQuery= module("jquery");

Both plugin1 and jQuery will have seperate versions of the jQuery interface, plugin1 does not add to the interface defined in the jquery module.

I have tried naming the modules in each file the same

export module jQuery {
   // .., jQuery definitions
}

but it still doesnt work

Community
  • 1
  • 1
Adam Mills
  • 7,719
  • 3
  • 31
  • 47

3 Answers3

2

Add the following to the end of the jquery.d.ts file on github/definetelytyped.

declare module "jquery"{ 
 /****
 AJAX
*****/
export function ajax(settings: JQueryAjaxSettings): JQueryXHR;
export function ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;

export function  ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
export function ajaxPrefilter(handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;

export var ajaxSettings: JQueryAjaxSettings;

export function ajaxSetup(options: any);

export function get(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
export function getJSON(url: string, data?: any, success?: any): JQueryXHR;
export function getScript(url: string, success?: any): JQueryXHR;

export function param(obj: any): string;
export function param(obj: any, traditional: bool): string;

export function post(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;

/*********
 CALLBACKS
**********/
export function Callbacks(flags?: string): JQueryCallback;

/****
 CORE
*****/
export function holdReady(hold: bool): any;
export function (selector: string, context?: any): JQuery;
export function (element: Element): JQuery;
export function (object: { }): JQuery;
export function (elementArray: Element[]): JQuery;
export function (object: JQuery): JQuery;
export function (func: Function): JQuery;
export function (array: any[]): JQuery;
export function (): JQuery;

export function noConflict(removeAll?: bool): Object;

export function when(...deferreds: any[]): JQueryPromise;

/***
 CSS
****/
export function css(e: any, propertyName: string, value?: any);
export function css(e: any, propertyName: any, value?: any);
export var cssHooks: { [key: string]: any; };
export var cssNumber: any;

/****
 DATA
*****/
export function data(element: Element, key: string, value: any): any;
export function data(element: Element, key: string): any;
export function  data(element: Element): any;

export function dequeue(element: Element, queueName?: string): any;

export function hasData(element: Element): bool;

export function queue(element: Element, queueName?: string): any[];
export function queue(element: Element, queueName: string, newQueueOrCallback: any): JQuery;

export function removeData(element: Element, name?: string): JQuery;

/*******
 EFFECTS
********/
export var fx: { tick: () => void; interval: number; stop: () => void; speeds: { slow: number; fast: number; }; off: bool; step: any; };

/******
 EVENTS
*******/
export function proxy(context: any, name: any): any;
export function Deferred(): JQueryDeferred;

/*********
 INTERNALS
**********/
export function error(message: any);

/*************
 MISCELLANEOUS
**************/
export var expr: any;
export var fn: any;  //TODO: Decide how we want to type this
export var  isReady: bool;

/**********
 PROPERTIES
***********/
export var browser: JQueryBrowserInfo;
export var support: JQuerySupport;

/*********
 UTILITIES
**********/
export function contains(container: Element, contained: Element): bool;

export function each(collection: any, callback: (indexInArray: any, valueOfElement: any) => any): any;

export function extend(target: any, ...objs: any[]): Object;
export function extend(deep: bool, target: any, ...objs: any[]): Object;

export function globalEval(code: string): any;

export function grep(array: any[], func: any, invert: bool): any[];

export function inArray(value: any, array: any[], fromIndex?: number): number;

export function isArray(obj: any): bool;
export function isEmptyObject(obj: any): bool;
export function isFunction(obj: any): bool;
export function isNumeric(value: any): bool;
export function isPlainObject(obj: any): bool;
export function isWindow(obj: any): bool;
export function isXMLDoc(node: Node): bool;

export function makeArray(obj: any): any[];

export function map(array: any[], callback: (elementOfArray: any, indexInArray: any) =>any): JQuery;

export function merge(first: any[], second: any[]): any[];

export function noop(): any;

export function now(): number;

export function parseJSON(json: string): Object;

//FIXME: This should return an XMLDocument
export function parseXML(data: string): any;

export function queue(element: Element, queueName: string, newQueue: any[]): JQuery;

export function trim(str: string): string;

export function type(obj: any): string;

export function unique(arr: any[]): any[];
}

Then just use:

import $ = module("jquery");

This assumes your js file for jquery is in the same directory and named jquery.js. You can see the sample I have in the downloads section of my blog.

Ian Drake
  • 121
  • 1
  • 3
2

Typescript won't import modules unless they export something and unless you directly use what they exported, but those things aren't true for things like JQuery plugins that simply add new methods to $. The solution is to use the amd-dependency flag as documented here.

Add a line like this at the top of your file:

///<amd-dependency path="jgrowl" />

This will force Typescript to list it in the define invocation in the compiled Javascript. You'll also need to set up a path and shim for your plugin in your require.config, like this:

require.config({
  paths: {
    jquery: "external/jquery-2.1.1",
    jgrowl: "external/jquery.jgrowl-1.4.0.min",
  },
  shim: {
    'jgrowl': { deps: ['jquery'] },
  }
});
Eric Lee
  • 8,181
  • 4
  • 21
  • 18
  • Is this still correct solution for importing jQuery plugin that I don't want to use directly? It does still work, hence the upvote - just wondering if there's a different preferred method at this point. – Joseph Gabriel Oct 07 '16 at 13:02
0

You would need to load it with an import statement and add the definition file with a reference.

///<reference path="jquery.templ.d.ts" />

import plugin = module("jquery.templ");
Fenton
  • 241,084
  • 71
  • 387
  • 401
  • That doesn't seem to work for me, the jQuery interface is not extended. What does the jquery.templ.d.ts file look like? Does it export its own module name or does it export under the jquery module name? – Adam Mills Nov 26 '12 at 11:21
  • Normally the jquery definitions just add to the jquery interfaces... i.e. `interface JQuery { myThing: myType; }` – Fenton Nov 26 '12 at 14:11
  • updated the question, when using modules (i.e. the jQuery definitions are wrapped in export module jQuery {}) the interfaces are dont get extended, you end up with two seperate jQuery interfaces – Adam Mills Nov 26 '12 at 14:47
  • I wouldn't wrap them in a jQuery module - jQuery is an interface in `jquery.d.ts`, so I would extend that interface. – Fenton Nov 26 '12 at 15:53
  • that also doesn't work as the extensions are still defined in plugin variable, the jquery variable contains the original unextended version. – Adam Mills Nov 26 '12 at 18:45