繁体   English   中英

ExtJS 5 的 TypeScript 定义

[英]TypeScript definitions for ExtJS 5

有人在为 ExtJS 5 研究 TypeScript 定义吗? 我一直在检查绝对类型,但没有活动:

https://github.com/borisyankov/DefinitelyTyped/tree/master/extjs

我开始认真研究这个问题,但发现搜索结果相当不令人满意。

首先,这里有一个小讨论,它提供了对 Sencha 对 TypeScript 的看法的一些见解

虽然我找不到任何特定于 ExtJS 5 的内容(抱歉),但我确实找到了这个链接,它声称使用以 ExtJS 文档开头的过程生成 TypeScript 声明文件。 这些示例针对 ExtJS 4.1,但也许它可以与 ExtJS 5 一起使用。如果是这样,它将解决您的问题。 这当然不是答案,但也许是线索。


顺便说一句,上面提到的谈话并不适合我。 它始于一个看似无害的请求,让 Sencha 考虑 TypeScript 为静态工具提供的潜力。

打字稿

我刚刚发现了 TypeScript ( http://www.typescriptlang.org/ ),它看起来很有希望。 有没有人有机会玩它? 我想了解是否可以生成一个 TypeScript 声明文件来声明来自 Ext JS 和 Sencha Touch 框架的所有类型。 我很想为我的 Sencha 开发工作提供更好的静态分析和工具支持。

谢谢!

这是来自 Sencha 高级论坛经理的回应:

另一件事让事情变得丑陋[TypeScript]

[编辑] 不管我说这条评论多少次显然是个人评论,它仍然是个人评论。 如果你没有和我交谈过或在 Twitter 上关注我或任何东西,我对我的代码和 TypeScript(甚至 ES6)的语法很丑陋。

真是太狠了!

我个人不认识论坛经理,所以我不会谈论他对 TypeScript 的特殊偏见。 但我确实认为我可以提供一些见解,说明为什么 Sencha 代表可能不支持它的成功。 也许这会帮助您理解为什么许多人可能不会优先考虑为 ExtJS 5 创建定义文件。

请注意,我可能是错的,那里有一个 ExtJS 5 定义文件,但还没有将它加入到确定类型中。 我的搜索远非详尽无遗。

打字稿

这是 TypeScript 使用的面向对象编程模型的一个简单示例。 . 请注意,构造函数是一个函数,它返回一个实例,该实例的状态可能已从其原型的状态修改或特化:

function Mammal() {
    //...  
}

构造函数的原型属性恰好是构造函数返回的对象的原型,然后可以使用方法和属性进行扩展(在 ES5 Object.defineProperty 意义上)。 不必为构造函数创建的每个实例重新创建在原型上声明的成员:

Mammal.prototype = function giveBirth() {
    //...
}

从这个意义上说,构造函数扮演了一个类的角色,它的原型属性的结构定义了构造函数创建的对象的类型。 虽然这种模式在 ES3 和 ES5 中相当冗长,尤其是在添加继承所需的额外机制时,但 ES6 使用它来定义类的概念。 因此,它是 TypeScript 编译器用来编译类的模式。

要更完整地处理 JavaScript 中这种经典的面向对象编程形式,以及使经典继承更加简洁的技术,请参阅Douglas Crockford 的这篇文章

值得注意的是,类型的概念仅存在于设计时,并且由 TypeScript 编译器强制执行以帮助您编写更可靠的代码。

扩展JS

在 TypeScript 出现之前,我已经熟悉 Sencha 的 ExtJS 框架采用的经典继承模型。 该模型提供了一种使用多种模式(包括模块模式原型模式工厂模式)定义类并从其相应类型创建实例的方法。 如果您是 ExtJS 程序员,您会发现这些模式非常熟悉,但作为参考,请参阅 Addy Osmani 编写Learning JavaScript Design Patterns的相应部分。

作为一个纯 JavaScript 开发者,这种经典的面向对象编程方法非常强大。 它在许多方面与 TypeScript 编译器使用的经典面向对象编程模型相似,但有一个关键区别。 在 ExtJS 中,类及其类型是框架已知的,因此在运行时存在。 ExtJS 最好的事情之一是它模拟了创建类的语法,就像在 Java 或 C# 中所做的一样。 但与在 TypeScript 中指定类的方法相比,它显得苍白无力。

刚开始介绍时,我对 ExtJS 使用的类定义方法非常着迷,于是我创建了一个自己的库,称为classic 我受到了足够的启发,创建了自己的库,以便探索和扩展 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 定义的运行时类型系统。 这两种类型系统在实现方式方面非常相似,但它们都有不同的语法,因此必须单独指定。 如果必须维护每个接口的两个副本,则静态类型系统的大部分价值都会丢失。

这是对集成 TypeScript 和 ExtJS 时必须克服的障碍的更完整处理 它还引用了上面的 GitHub 项目。 作者得出的结论是

不幸的是,TypeScript 和 ExtJs 似乎不能很好地协同工作。

最重要的是,ExtJS 和 TypeScript 都定义了自己的类型系统,它们的规则并不完全相同。 因此 ExtJS 和 TypeScript 从根本上是不兼容的......

...从根本上说是一个词太强了,但是要有效地将这两个工具一起使用需要做很多工作。 因此,如果我是 Sencha 的高级论坛经理,我可能也不会支持 TypeScript。

就个人而言,我更喜欢 ES6 预览版、静态类型系统和 TypeScript 提供的设计时工具。 很遗憾我什至不得不选择,因为两者不是同一类型- 一个是框架,另一个是语言。 有些人确实不遗余力地使它们兼容

ExtJS 是一个强大的 JavaScript 框架,我相信它只会随着时间的推移变得更加丰富。 但事实上,当用作 JavaScript 框架时,ExtJS 处于最佳状态。 或者引用同一个论坛管理员的话:

...您可以编写正确且高效的 JavaScript,而无需任何编译器,如 coffeescript 或 typescript。

ExtJS 作为框架提供了一种在 JavaScript 中实现经典的面向对象继承的方法。 TypeScript 提供了第二种方法作为语言。 如果您对 TypeScript 感兴趣,请查看经典的. 它远不是像 ExtJS 这样的专业框架,但它确实提供了关于为 TypeScript 开发人员构建的工具可能是什么样子的意见。

我最近一直在研究 ExtJS 的一些 Typescript 定义,并且还参与了另一个项目,该项目提供了一个与 ExtJS 更兼容的分叉 Typescript 编译器。

https://github.com/fabioparra/TypeScript

请去寻找 ExtTS - Sencha Ext JS 的高级 TypeScript 类型定义

https://github.com/thanhptr/extts

几乎支持 ExtJS 4.x、5.x、6.x 的所有最新版本,目前最新版本为 6.0.2.437。

您可以从 ExtJS API 文档中找到的所有内容都在具有强类型支持的类型定义中(例如:Ext.dom.Element、ButtonConfig 等)

也许我在事情不再是最新的一段时间后回答,但我创建了
Ext.JS 5、6 和 7 的 TypeScript 定义,因为有很多原因
不要走上面的路:

  • 打补丁的 TypeScript 编译器不再处于活动状态。 今天的 TypeScript 版本离它很远。
  • 打补丁的 TS 编译器很酷,但是 TS 编译器太复杂了,无法维护
    (用于生成 Ext.JS 类)对我来说。
  • https://github.com/thanhptr/extts上的“高级 TypeScript 定义”有
    很多错误,我的意思很多。 例如你需要的第一个电话
    Ext.application({}); 无处可去。
  • github.com/thanhptr/extts中的 JS 文档包含 HTML 语法,这对于日常工作来说不太可读。
  • 在Ext.JS打字稿发电机github.com/zz9pa/extjsTypescript过于简单,不可能
    用于更高的 Ext.JS 版本(5、6 和 7),但它是创建的主要冲动
    新的Ext.JS TypeScript 定义生成器在这里。

我的解决方案基于与此博客文章相同的原则:“ 使用 ExtJs 和 TypeScript ”。
但是有一些区别。 我认为所有差异都可以从示例中清楚地看出:

主要区别是:

  • 所有类都按原样生成。
  • 还会生成“覆盖”文件中的所有成员。
  • ExtExt.Array等单例类也可以正确生成。
  • 类配置放在*.Cfg接口中,例如:
    Ext.panel.PanelExt.panel.Panel.Cfg有配置接口。
  • 要扩展类,您需要的不仅仅是类配置(您需要像
    extendrequiresconfigstatics或模板方法),
    所以这就是为什么生成的接口具有扩展类定义:
    Ext.panel.Panel扩展的类具有在Ext.panel.Panel.Def定义的Ext.panel.Panel.Def
  • 还有以更好的方式生成的self属性。
  • 有为监听器/事件生成的接口,例如: Ext.panel.PanelExt.panel.Panel.Events有事件接口。
  • 还为结构化方法参数等生成了很多接口。

当然可以使用现代工具包创建应用程序,但 Id 没有提供任何示例:-)。

该解决方案支持随处自动完成通过 CTRL+R 重构Visual Studio 代码,非常实用:-)

ExtJS TS 定义肯定有空间虽然 TypeScript 和 ExtJS 使用不兼容的类系统是真的,但某些策略可以用作解决方法:

使用打过补丁的 TS 编译器

由 fabioparra 开发并由 Gareth 在此处链接的 ExtJS 发射器是一种可能的解决方法。 恕我直言,主要缺点是它使与支持 TS 语言的 IDE 的集成复杂化。 例如,没有关于此解决方案与现有 Eclipse TS 插件兼容性的文档。 此外,不确定是否会为 TypeScript 的未来版本维护补丁的开发。

使用 TS 静态方法作为 ExtJS 对象的工厂

这里的想法是提供一组静态方法来替换 ExtJS 类的构造函数。 因此,可以在使用旧版 TS 编译器的同时实例化 ExtJS 对象。 我最近在 github ( https://github.com/david-bouyssie/TypExt ) 上发布了这个名为 TypExt 的替代解决方案。 请注意,它必须与适当的 ExtJS TS 定义( https://github.com/david-bouyssie/TypExt/tree/master/typescripts )结合使用。 目前仅支持 ExtJS 5.1.1,但我计划将 TypExt 的使用扩展到其他 ExtJS 版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM