6

我有许多 jQuery 插件,我想在 TypeScript 中使用 AMD 模式加载它们。例如,我可能有这样的结构:

/lib/jquery.myplugin.js
/app.ts

该插件只是扩展了 jQuery。它没有提供新的顶级函数或变量。一个例子可能是:

// jquery.myplugin.js
jQuery.fn.myExample = function() { ... }

对应的 jquery.myplugin.d.ts 文件如下所示:

interface JQuery {
    myExample();
}

所以现在在 app.ts 我可以调用类似$('#my-element').myExample(). 请注意,这假设我已经加载了 Microsoft 的 jquery.d.ts 声明。

我的问题是如何异步加载这个库并利用 TypeScripts 静态类型?我可以这样使用它:

/// <reference path="lib/jquery.myplugin.d.ts"/>

但这需要我在<script>我的 HTML 中添加一个标签,并且该库不是异步加载的。我希望 TypeScript 生成此代码:

define(["require", "exports", "lib/jquery.myplugin"], function (require, exports, __jquery.myplugin__) {
    ...
    // Use my plugin
    $('#my-element').myExample();
}

但是,由于 .d.ts 文件中没有导出,我无法编写import myplugin = module('lib/jquery.myplugin')

我得到的最接近的是jquery.myplugin.d.ts使用接口声明引用另一个 ts 文件并包含至少一个导出。然而,在这个库中没有什么要导出的,为了获得所需的输出,我不仅要添加一个导出,而且我必须调用它。

更新:我在typescript.codeplex.com上为此打开了一个工作项

4

3 回答 3

4

Kind of a hack but here's the only way I currently know of.

myplugin.d.ts: extends the JQueryStatic interface to include intellisense for myplugin's functionality

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

interface JQueryStatic {
    myFunc(): string;
}

myplugin.ts: a dummy file whose only purpose is to have typescript generate an amd module definition.

var test: number = 1;

consumer.ts:

/// <reference path="myplugin.d.ts" />

import myplugin = module('myplugin');

// without this typescript knows you aren't actually using the module
// and won't create the define block including your plugin
var workaround = myplugin.test;

$.myFunc();

consumer.js: generated with tsc -c --module amd consumer.ts

define(["require", "exports", 'myplugin'], function(require, exports, __myplugin__) {
    /// <reference path="myplugin.d.ts" />
    var myplugin = __myplugin__;

    // without this typescript knows you aren't actually using the module
    // and won't create the define block including your plugin
    var workaround = myplugin.test;
    $.myFunc();
})

Note that myplugin.d.ts will pull intellisense in for both jQuery and your plugin definitions. It was necessary to create both a myplugin.d.ts and myplugin.ts because I don't know how (if possible) to export something while simultaneously extending an existing interface in the same file without errors.

于 2012-10-22T17:48:18.280 回答
3

Typescript 不会导入模块,除非它们导出一些东西,除非你直接使用它们导出的东西,但是对于像 JQuery 插件这样简单地将新方法添加到 $. 解决方案是使用此处记录的 amd-dependency 标志。

在文件顶部添加这样的一行:

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

define这将强制 Typescript在已编译的 Javascript的调用中列出它。您还需要在 require.config 中为您的插件设置路径和填充程序,如下所示:

require.config({
  paths: {
    jquery: "external/jquery-2.1.1",
    jgrowl: "external/jquery.jgrowl-1.4.0.min",
  },
  shim: {
    'jgrowl': { deps: ['jquery'] },
  }
});
于 2014-12-12T01:36:57.843 回答
1

在定义接口的文件的底部,您可以放置​​:

export var JQuery: JQueryStatic;

这将使 JQuery 的智能感知显示在使用import module.

如果您的文件正在异步加载并且您将JQuery设置为另一个变量(即myJQuery),您可以声明该文件已经在某个时间点加载,例如,如果您的文件中有文件,您///<reference path=...>应该能够利用:

declare var myJQuery: JQuery;

使您的myJQuery类型为JQuery

另一个技巧是将接口直接插入到异步加载代码的区域:

interface JQueryStatic {
    myFunc(): string;
}

如果您不介意编辑 JQuery.d.ts 文件,可以将函数添加到其中定义的接口中。

与您的示例相关,您应该能够执行以下操作:

declare var __jquery : JQueryStatic;

在定义回调的顶部;并且如果您已经扩展了JQueryStatic的接口并使用标记包含它///<reference path=...>应该可以按需要工作。

于 2013-02-01T06:14:36.697 回答