The issue with jQuery plugins (and other plugin based libraries) is that not only do you need a library.d.ts file for the base library, but you also need a plugin.d.ts file for each plugin. And somehow thes plugin.d.ts files need to extend the library interfaces defined in the library.d.ts files. Fortunately, TypeScript has a nifty little feature that lets you do just that.
With classes
there currently can only be a single cononical definition of a class within a project. So if you define a class Foo
the members you put on Foo
are all you get. Any additional definitions of Foo
will result in an error. With interfaces
, however, the members are additive so if you define interface Bar
with a set of members you can define 'interface Bar' a second time to add additional members to the interface
. That's the key to supporting jQuery plugins in a strongly typed way.
So to add support for a given jQuery plugin you're going to need to create a plugin.d.ts file for the plugin you want to use. We use jQuery Templates in our project so here's the jquery.tmpl.d.ts file we created to add support for that plugin:
interface JQuery
{
tmpl(data?:any,options?:any): JQuery;
tmplItem(): JQueryTmplItem;
template(name?:string): ()=>any;
}
interface JQueryStatic
{
tmpl(template:string,data?:any,options?:any): JQuery;
tmpl(template:(data:any)=>string,data?:any,options?:any): JQuery;
tmplItem(element:JQuery): JQueryTmplItem;
tmplItem(element:HTMLElement): JQueryTmplItem;
template(name:string,template:any): (data:any)=>string[];
template(template:any): JQueryTemplateDelegate;
}
interface JQueryTemplateDelegate {
(jQuery: JQueryStatic, data: any):string[];
}
interface JQueryTmplItem
{
data:any;
nodes:HTMLElement[];
key:number;
parent:JQueryTmplItem;
}
Breaking this down the first thing we did is to define the methods that get added to the JQuery
interface. These let you get intellisense and type checking when you type $('#foo').tmpl();
Next we added methods to the JQueryStatic
interface which show up when you type $.tmpl();
And finally the jQuery Templates plugin defines some of its own data structures so we needed to define interfaces for those structures.
Now that we have the additional interfaces definied we just need to reference them from the consuming .ts files. To do that we just add the references below to the top of our .ts file and that's it. For that file, TypeScript will see both the base jQuery methods and the plugin methods. If you use multiple plugins just make sure you refernce all of your individual plugin.d.ts files and you should be good.
/// <reference path="jquery.d.ts"/>
/// <reference path="jquery.tmpl.d.ts" />
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…