没有导出的TypeScript声明的异步加载

时间:2012-10-22 16:42:40

标签: javascript typescript js-amd

我想在TypeScript中使用AMD模式加载一些jQuery插件。例如,我可能有这种结构:

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

但是这需要我在我的HTML中添加<script>标记,并且不会异步加载库。我希望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')

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

更新:我在work item

上为此打开了typescript.codeplex.com

3 个答案:

答案 0 :(得分:4)

有点像黑客,但这是我目前唯一知道的方式。

myplugin.d.ts :扩展JQueryStatic接口以包含用于myplugin功能的intellisense

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

interface JQueryStatic {
    myFunc(): string;
}

myplugin.ts :一个虚拟文件,其唯一目的是让typescript生成amd模块定义。

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 :使用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();
})

请注意, myplugin.d.ts 会为jQuery和插件定义提取intellisense。有必要同时创建一个myplugin.d.ts和myplugin.ts,因为我不知道如何(如果可能的话)导出某些内容,同时在同一文件中扩展现有接口而没有错误。

答案 1 :(得分:3)

Typescript不会导入模块,除非他们导出某些东西,除非你直接使用他们导出的内容,但是对于像JQuery插件这样简单地向$添加新方法的东西来说这些都不是真的。解决方案是使用记录为here的amd-dependency标志。

在文件顶部添加如下所示的行:

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

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

require.config({
  paths: {
    jquery: "external/jquery-2.1.1",
    jgrowl: "external/jquery.jgrowl-1.4.0.min",
  },
  shim: {
    'jgrowl': { deps: ['jquery'] },
  }
});

答案 2 :(得分:1)

在文件底部定义了界面,您可以输入:

export var JQuery: JQueryStatic;

这将使JQuery的intellisense显示在使用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=...>将其包含在内,则标记应该可以正常工作。

相关问题