我开始认真研究这个问题,但发现搜索结果并不令人满意。
首先,here is a small discussion which provides some insight into Sencha's view on TypeScript。
虽然我找不到任何特定于 ExtJS 5 的内容(我深表歉意),但我确实找到了 this link,它声称使用以 ExtJS 文档开头的流程生成 TypeScript 声明文件。这些示例针对 ExtJS 4.1,但也许它可以与 ExtJS 5 一起使用。如果是这样,它将解决您的问题。这当然不是答案,但也许是线索。
顺便说一句,上面提到的对话并不适合我。它始于一个看似天真的要求 Sencha 考虑 TypeScript 为静态工具提供的潜力。
打字稿
我刚刚发现了 TypeScript (http://www.typescriptlang.org/),它
看起来很有希望。有人有机会玩它吗?
我想了解是否可以生成 TypeScript
声明文件来声明来自 Ext JS 和 Sencha 的所有类型
触摸框架。我希望有更好的静态分析和工具
支持我的 Sencha 开发工作。
谢谢!
这是 Sencha 高级论坛经理的回复:
让事情变得丑陋的另一件事[TypeScript]
[编辑] 不管我说多少次,这条评论显然是
个人评论,还是个人的。如果你还没有和我说话或
在 Twitter 上关注我或其他任何事情,我对我的代码和
TypeScript(甚至 ES6)的语法很丑。
这太苛刻了!
我个人不认识论坛管理员,所以我不会谈论他对 TypeScript 的特殊偏见。但我确实认为我可以提供一些见解,说明为什么 Sencha 的代表可能不支持它的成功。也许这会帮助您理解为什么对于许多人来说,为 ExtJS 5 创建定义文件可能不是一个高优先级。
请注意,我可能错了,那里有一个 ExtJS 5 定义文件,但它还没有进入 DefinitiveTyped。我的搜索远非详尽。
TypeScript
Here is a simple example of the model of object-oriented programming that TypeScript uses.。请注意,构造函数是一个函数,它返回一个实例,该实例的状态可能已从其原型的状态修改或特化:
function Mammal() {
//...
}
构造函数的原型属性,恰好是构造函数返回的对象的原型,然后可以使用方法和属性进行扩展(在 ES5 Object.defineProperty 意义上)。在原型上声明的成员不必为构造函数创建的每个实例重新创建:
Mammal.prototype = function giveBirth() {
//...
}
从这个意义上说,构造函数扮演着一个类的角色,其原型属性的结构定义了构造函数创建的对象的类型。虽然这种模式在 ES3 和 ES5 中非常冗长,尤其是在添加继承所需的额外机制时,但它是 ES6 用来定义类概念的模式。因此,它是 TypeScript 编译器用来编译类的模式。
如需更完整地处理这种在 JavaScript 中的经典面向对象编程形式,以及使经典继承更简洁的技术,请参阅 this post by Douglas Crockford。
值得注意的是,类型的概念仅在设计时存在,并且由 TypeScript 编译器强制执行,以帮助您编写更坚固的代码。
ExtJS
在 TypeScript 出现之前,我已经熟悉 Sencha 的 ExtJS 框架采用的经典继承模型。该模型提供了一种方法来定义类并使用多种模式从其对应类型创建实例,包括模块模式和原型模式和工厂模式时间>。如果您是 ExtJS 程序员,您会发现这些模式非常熟悉,但作为参考,请参阅 Addy Osmani 的 Learning JavaScript Design Patterns 的相应部分。
作为一个纯 JavaScript 开发者,这种经典的面向对象编程的方法很强大。它在许多方面与 TypeScript 编译器使用的经典面向对象编程模型相似,但有一个关键区别。在 ExtJS 中,类及其类型是框架已知的,因此存在于运行时。 ExtJS 最好的事情之一是它模拟了创建类的语法,就像在 Java 或 C# 中所做的那样。但与TypeScript中指定类的方法相比,就显得苍白无力了。
当我第一次被介绍时,我对 ExtJS 使用的类定义方法非常着迷,以至于我创建了一个自己的库,名为 classical。我受到了足够的启发,创建了自己的库,以便探索和扩展 JavaScript 中的类定义,并为我自己的启迪而实现它。如果您单击上面的链接,您会注意到该项目已经从类似 ExtJS 的类系统演变为 TypeScript 的基类库。
为什么要改变?
首先,TypeScript 提供了一个面向对象的编程模型,它不仅让我能够利用熟悉的 OOP 设计模式,而且还为我提供了一个静态类型系统和与之配套的所有设计时工具。当第一次发现 TypeScript(0.8 版)时,我最初的反应是为经典创建一个类型定义文件,这与为 ExtJS 创建一个类似(但更简单)的努力。在我完成这个任务之后,生成的库的语法是一场彻底的灾难!我想探讨一下出了什么问题,我将使用 ExtJS 中的一个简单示例来做这件事。
这段代码取自上述讨论,看起来像一个标准的 ExtJS 类定义:
Ext.define('WebApp.model.RenderableRecord', {
extend: 'Ext.data.Model',
idPropert: 'id',
isRenderableRecord : true,
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' },
{
name: 'renderable',
convert: function (val, model) {return val;}
},
],
renderItems: function (renderer: Function) {
var me = this;
return function (config: Object) {
renderer(me.get('renderable'), config);
}
},
});
考虑上面原型定义的接口。如果需要 TypeScript 中的静态类型,可以创建一个看起来像这样的界面:
module WebApp {
module model {
export interface RenderableRecord extends Ext.data.Model {
idPropert: string;
isRenderableRecord: boolean;
fields: Array<Field>;
renderedItems(renderer: Function);
}
//Assume Ext.data.Model and Field are defined already
//and that the Field interface looks something like this:
export interface Field {
name: string;
type: string;
convert: Function;
}
}
}
不仅该接口必须与 ExtJS 定义一起定义,而且实例的类型必须指定两次,一次作为 WebApp.model.RenderableRecord(或者在调用 Ext.create 时作为同名字符串)然后再次将其转换为适当的 TypeScript 类型。获得静态类型需要做很多工作,也就是说,由于强制转换,仍然容易出错!
那么问题出在哪里?
问题是有两种类型系统在起作用。一种是由 TypeScript 编译器强制执行的设计时类型系统。另一种是ExtJS定义的运行时类型系统。这两种类型系统在实现方式上非常相似,但它们都有不同的语法,因此必须单独指定。如果必须维护每个接口的两个副本,则静态类型系统的大部分价值都会丢失。
Here is a more complete treatment of the hurdles that one must overcome when integrating TypeScript and ExtJS。它还引用了上面的 GitHub 项目。作者的结论是
不幸的是,TypeScript 和 ExtJs 似乎不太好用
在一起。
底线是 ExtJS 和 TypeScript 都定义了自己的类型系统,它们的规则并不完全一样。因此 ExtJS 和 TypeScript 从根本上是不兼容的......
...好吧从根本上说这个词太强了,但是要有效地同时使用这两个工具需要做很多工作。所以如果我是 Sencha 的高级论坛经理,我可能也不会支持 TypeScript。
就个人而言,我更喜欢 ES6 预览版、静态类型系统和 TypeScript 提供的设计时工具。遗憾的是,我什至不得不选择,因为两者的类型不同——一个是框架,另一个是语言。有些人肯定会go to great lengths to make them compatible。
ExtJS 是一个强大的 JavaScript 框架,我敢肯定它只会随着时间的推移变得更加丰富。但事实上,ExtJS 在用作 JavaScript 框架时是最好的。或者引用同一个论坛经理的话:
...您可以编写正确且高效的 JavaScript,而无需
任何编译器,如 coffeescript 或 typescript。
ExtJS 提供了一种在 JavaScript 框架中实现经典的面向对象继承的方法。 TypeScript 作为一种语言提供了第二种方法。如果您对 TypeScript 感兴趣,请查看 classical。它与 ExtJS 之类的专业框架相去甚远,但它确实提供了关于为 TypeScript 开发人员构建工具时的外观。