我和我的团队正在构建一个使用较早版本流行JavaScript库(jQuery,Backbone,Underscore等)的大型Web应用程序项目。我们目前正在尝试使用TypeScript来解决新的解决方案以及替换现有的JavaScript代码。因为我们的项目严重依赖特定的JS库版本(例如jQuery 1.8.3),所以将这些库更新为最新版本稍微复杂一些,不仅仅是下载和下载最新版本。将更新日期的JavaScript库与更新后的TypeScript集成
这对我们来说在逐步改变TypeScript方面会产生一个问题;我们需要声明与最新的TypeScript标准兼容的过时的JS库版本。虽然DefinitelyTyped在提供申报文件的 最新版本 JS库的特定于最新版本打字稿的做了伟大的工作,它不为年长 JS库版本能与最新的兼容提供报关文件TypeScript标准。
看起来,随着TypeScript的发展,所有较旧的库声明(例如jQuery-1.8.3.d.ts)都被留下了,因为这些库同时在不断发展。这是完全可以理解的,因为我不希望社区中有很多努力不断更新日期库的声明文件,以便它们与新的TypeScript标准兼容。
所以我的问题是:什么是最好的方式来逐步在新的TypeScript代码,严重依赖老的JS库?
下面是我遇到的一个问题的例子。我基本上试图用TypeScript创建一个Backbone应用程序。
// Model.ts
import Backbone = require("backbone");
export class NewModel extends Backbone.Model {
...
}
而且因为我们使用了AMD require.js我们得到类似以下内容:
// Model.js
...
define(['require', 'exports', 'backbone'], function(require, exports, Backbone) {
...
}
这是伟大的,它正是我们希望,因为我们require.config文件的输出定义了所有我们需要的库:
// Config.ts
require.config({
baseUrl: './',
paths: {
'jquery': '../jquery-1.8.3.min',
'underscore': '../underscore/underscore.min',
'backbone': '../backbone/backbone',
'text': '../require/text'
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
然而,打字稿不会让除非我们有一个backbone.d我们编译这段代码.ts,它描述了我们的backbone.js库的结构,并提供了“主干”模块的环境声明。
// backbone.d.ts
declare module Backbone {
...
export class Model extends ModelBase {
...
}
...
}
declare module 'backbone' {
export = Backbone;
}
// Model.ts
/// <reference path="path/to/backbone.d.ts" />
import Backbone = require("backbone")
export class NewModel extends Backbone.Model {
...
}
如果我们没有这些声明,然后我们有骨干模块的周围没有申报,因此可以在不打字稿因为extend Backbone.Model
是Backbone.Model
任何地方没有定义为一类。这是一个夸大的示例问题,因为Model
类类型存在于所有'backbone.d.ts'文件中,而不考虑版本。然而,如果你没有一个精确的.d.ts文件来代表它,那么JS库会有更微妙的变化,导致代码崩溃。这就是说,你也可以使用更新版本的.d.ts文件(我们一直在做),只要你只使用实际存在相关JS库的部分,并且作为只要你直接使用它们。否则,如果你使用一个不存在的函数,或者如果你传递了一个函数太多的参数,那么当这个函数实际被调用时你只会看到这个错误。 TypeScript不会选择它,因为它的信息完全基于.d.ts文件。
// Model.ts
/// <amd-dependency path="backbone" />
var Backbone = require("backbone");
export class NewModel extends Backbone.Model {
...
}
这将产生以下:
我们可以使用AMD依赖工作周围的东西,如产生define
要求
// Model.js
...
define(['require', 'exports', 'backbone'], function(require, exports) {
var Backbone = require('backbone');
...
}
这给了我们Backbone
引用,我们希望但是TypeScript仍然抱怨,因为它不知道我们声明的Backbone
变量。换句话说,它不提供.d.ts文件提供的结构。
尽管我们缺乏.js文件与其关联的.d.ts文件之间的关联,但我们的大多数TypeScript解决方案实际上都在按照他们应该的方式工作。我的关注点是:未来的这种差异会在我们的应用程序中造成重大问题吗?
现在,我能想到的最好的解决方案是:
- 获取.d.ts版本最接近我们JS库的版本和更新他们,使他们与最新的打字稿标准兼容。
- 使用最新的.d.ts文件,并在遇到问题时相应地更新它们。
我对任何一种解决方案都不是特别激动,这就是为什么我要伸出援手寻求另一种意见。如果有人仍然在这里(抱歉拖延这一点),那么我会很感激你提出的解决方案。