Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

Using jQuery plugin in TypeScript

When using typescript do I need to import a plugin.d.ts for every external js that I use? In other words, do I need to create a jQuery.d.ts with all the interfaces?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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" />

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...