本书首先介绍了TypeScript 的基本语法和基本的自动化工作流配置方法,然后从面向对象入手,着重介绍了面向对象的概念和它的一些最佳实践,并结合例子讲解了如何基于TypeScript 的类型系统应用这些最佳实践。随后剖析了TypeScript 在编译后的运行时行为,并从性能与测试的角度讲解了如何编写健壮的TypeScript 代码,所以书中还包括了性能分析与测试相关的内容。最后介绍了如何使用TypeScript 结合面向对象、MVC 等概念,结合本书前面提到的自动化的工作流、面向对象最佳实践、性能优化和测试等内容实现一个单页应用(SPA)框架,并用这个框架构建了一个单页应用。
首作问世 JavaScript重要方向 Angular 2构建基石
译者序
在 JavaScript社区的荒蛮时代里,构建大型 Web应用是一件吃力且烦琐的事情。但迫于业务发展的需要,业界一直在探索如何像成熟的工业化的语言那样开发和构建大型的应用。
微软在 2009 年发布了 TypeScript的第一个版本,它为 JavaScript 带来了类型系统与模块系统(现在已经废弃并鼓励使用 ES6模块)。而自从 TypeScript问世,JavaScript 社区就没有停止过对它的议论,有人认为类型系统给 JavaScript 带来的静态检查能力更有利于构建大型应用,而另一些人则认为类型系统会使 JavaScript 丧失其先天的灵活性和动态性,不利于提高开发效率。还有一些人担心 TypeScript为 JavaScript 带来了太多非标准的特性,很难保证 TypeScript在未来与 JavaScript在语言层面上保持高度统一。
译者在翻译本书前,刚刚经历了将一个 CoffeeScript应用全面使用 TypeScript重构。 CoffeeScript 从某种程度上来看完全是 TypeScript的对立面,它甚至比 JavaScript 更具动态性与灵活性。而在译者重构的这个项目中,代码量高达上万行,且包含数十个模块,之所以选择使用 TypeScript重构它,是因为日益增长的代码量与模块数使得团队协同开发的难度越来越大。
也正是因为这次重构,使译者能深入了解 TypeScript。它的类型系统异常强大,可以大大降低团队中成员的沟通成本。以往,团队中的成员需要调用另一个成员写的模块时,必须要仔细研究这个模块中各个 API 的参数、参数类型和返回值。然而因为项目中通常缺乏文档与注释(这是另外的讨论点),所以通常在使用其他人开发的模块时会占用程序员大量的时间去阅读和理解其他人的代码。而 TypeScript的类型系统无疑是给了我们一个快捷的文档,使得我们能更好更快地使用别人的模块。即使是在拥有良好的注释以及文档的模块中,TypeScript服务提供的 Intellisense 功能也能让开发人员如虎添翼,再也不用担心忘记参数类型或忘记方法名。
而另一方面, TypeScript过强的约束也在开发时给我们带来了很多额外的困扰。比如在开启了--noImplicitReturns参数后,一些设计成无返回值的代码将会导致编译失败,比如:
getOne(_id: string): string {
const result = cacheService.exist(_id)
if (result) {
return cacheService.findById(_id)
}
}
由于这段代码只有一个分支有返回值,所以它将导致编译失败,但我们正是期待代码这样运行。
同时,我们也接触到了一些 TypeScript 的私有功能,比如 enum(枚举)与 reflectMetaData(元数据反射)。出于对使用非标准特性的风险的考量,我们并没有在项目中使用这些特性。
除了强大的类型系统带来的可靠的静态检查以外,我们还惊喜地发现了一个能大大增加项目可维护性与健壮性的实践,那就是依靠 TypeScript的类与接口将面向对象的 SOLID原则应用到项目中,这无疑是搭了类似 Java 与 C# 等面向对象语言的顺风车,它能让我们更容易地写出高内聚低耦合的代码。
所以在面对社区各种对 TypeScript褒贬不一的评价时,希望读者能理性地看待这些声音,并且能够在深思熟虑之后进一步接触 TypeScript,深入了解它的优点与缺点,最终为自己的项目选择合适的工具。
关于作者
Remo H. Jansen是一位前端工程师、开源项目贡献者、企业家、科技爱好者、游戏爱好者和互联网爱好者。
他来自西班牙的塞维利亚,但目前居住于爱尔兰的都柏林,并在那里做着一份金融服务行业的全职工作。Remo有着多年的大型 JavaScript应用开发经验,从航班预定系统到投资组合管理解决方案。
Remo在 TypeScript社区中十分活跃。他是都柏林 TypeScript交流会的组织者,并且是 InversifyJS(一个 TypeScript应用的控制反转容器)和 AtSpy(一个 TypeScript应用的测试框架)的作者。在他的个人博客(http://blog.wolksoftware.com/)中,他写了许多关于 TypeScript和其他 Web技术的博客。
Remo也是由 Packt Publishing出版,Nathan Rozentals撰写的 Mastering TypeScript一书的技术审校者。
若想要与他取得联系,可以访问 http://www.remojansen.com/。
致谢
这是我出版的第一本书。在此之前,我经历了相当漫长的学习之路,并且从许多值得感谢的人那里,学到了许多知识。我首先要感谢地处特里亚纳圣彼得慈幼会(位于西班牙的塞维利亚)的计算机科学学
院中的老师们,因为他们让我体会到了教育的价值。感谢 Packt Publishing团队的成员们的支持和努力工作,与你们的合作十分愉快。感谢本书的所有技术审校者,他们无价的反馈和努力工作显著地提升了本书内容的质
量。感谢我的同事和室友,Sergio Pacheco Jimenez 和 Adolfo Blanco Diez,因为我常在半夜与前者进行漫长的技术交流,后者为我提供了大量咖啡饮料的支持。感谢我的女朋友,Lorraine,我为你无条件的支持和耐心深感荣幸。你就是世界上最好的女朋友,并且还在不断变得更好。
最后,感谢我的家人,感谢你们相信我,为我提供指导,成为我最好的倾听者,支持我的工作,原谅我所犯的错误,以及其他一切你们教会我的东西。感谢我们在一起所经历的开心与伤心的时光。能够成为你们的孙子、儿子和兄弟,让我十分骄傲。
关于审校者
Liviu Ignat是一位全栈工程师、架构师、科技极客和企业家,从 2004年以来开始编写商业软件。一开始使用的是 VB6,接着开始使用 .NET和 Java,后来转向了 Web前端开发。他对函数式语言十分感兴趣,如 F#、Scala、Swift、JavaScript等。在他的一些最新的服务端 Node.js项目和大多数使用流行前端框架的项目中已经使用上了 TypeScript。
目前,他正致力于许多项目,大多数项目是 http://giftdoodle.com/中的,他是这个公司的 CTO,这家公司中大多数 JavaScript项目都使用 TypeScript编写。在他的工作经历中,他使用.NET编写过分布式后端服务,也编写过复杂的单页 Web应用。最近他正致力于使用 Node.js和 Docker编写微服务,编写单页 Web应用,以编写 Android和 iOS原生应用。
当 Liviu不写代码时,他喜欢在冬天滑雪,在夏天坐帆船去国外,去世界的其他地方旅行。你可以在 http://www.ignat.email/联系到 Liviu。
Jakub Jedryszek目前是微软的一位软件工程师。在审校本书时,他工作于 Azure Portal,这是世界上使用 TypeScript编写的最复杂的单页 Web应用。他也是 .NET开发者的 dotNetConfPL——online会议的共同发起人之一。他的博客是 http://jj09.net/。
Andrew Leith Macrae最初在 Apple 的产品上开始了他的编程生涯。多年以来,他使用过 Hypercard、Director、Flash和最近的 Adobe AIR for mobile 开发交互式应用。并且在开发过程中,他也会用到 HTML。他目前是多伦多 Rogers Communications 公司的高级前端工程师,正在使用 AngularJS和 SASS进行敏捷开发。
他坚信 TypeScript是 JavaScript 的未来,TypeScript带来了强类型面向对象语言中的结构化和规则,为开发大规模 Web应用的代码编写提供了语义上的便利。
你可以在 http://adventmedia.net/联系到 Andrew。
Brandon Mills的编程生涯已经有十多年了,他就职过只有两个人的初创公司,也在微软就职过。他在微软参与了 Visual Studio 2013、Azure Tools 和预装于 Windows 10的 Edge浏览器项目。他也是 ESLint 项目的核心开发团队成员之一,这是一个开源可配置的 JavaScript和 JSX的语法检查工具。他目前在 Node.js平台上使用 JavaScript或 TypeScript编写应用和服务。他的 GitHub是 https://github.com/btmills。
感谢 Scott 的激励和给予我的灵感,感谢 Linda给予我无条件的爱,感谢 Abby给予我的耐心,以及感谢 Ashlynn 对我的支持。
Ivo Gabe de Wolff是一位 ivogabe(创始于 2012年)名下的自由职业开发者,他正在乌得勒支大学学习数学和计算机科学。当他只有 11岁时,便开始使用 Game Maker编写游戏程序。在学了诸如 C# 和 JavaScript等诸多编程语言后,他在现在的大多数项目中使用 TypeScript。在过去的几年里,他在许多不同的环境中使用过 TypeScript,如移动端应用。目前他主要致力于 Node.js 程序的开发。
另外,他也是许多开源项目的作者,包括 gulp-typescript。你可以在 https:// github.com/ivogabe中找到他的项目。如果你想阅读更多有关 TypeScript、JavaScript、 Gulp或数学的内容,也可以看看他的博客 http://dev.ivogabe.com/。
前言
在过去的几年里,基于 JavaScript的 Web应用的数量呈几何级数进行增长。但是,目前的 JavaScript标准( ECMAScript 5,又称 ES5)是在许多年前设计出来的,面对如今大规模 JavaScript应用的复杂性时,它缺少了许多必要的特性。正是由于这些特性的缺失,一些应用的可维护性问题暴露了出来。
新一代的 JavaScript标准(ECMAScript 6,又称 ES6),旨在解决上述可维护性问题。但它还没有完全实现,且现在我们使用的浏览器与之也不是完全兼容的。所以,ES6标准的广泛采用,仍被认为是一个漫长的过程。
为了解决这类 JavaScript的可维护和可扩展性问题,微软花了两年时间开发出 TypeScript,并在 2012年 10月,公开发布了它:
“我们为需要构建和维护大型 JavaScript程序的团队设计了 TypeScript,以满足他们的需求。TypeScript可帮助他们在软件组件之间定义接口,并且帮助理解现存 JavaScript库的行为。同时,使用 TypeScript的团队可以将代码构建成动态加载的模块,以减少命名冲突的问题。TypeScript可选的类型系统使开发者们可以使用一些高效的开发工具和最佳实践:静态检查,基于符号的导航,代码补全和代码重构。”
——TypeScript语言特性 1.0
即使是具有丰富经验的开发者,也很难给出大规模 JavaScript应用明确的定义。当谈及这个话题时,我们应该避免使用代码行数来作为评判标准,而是应该以代码中模块的数量和模块之间的依赖关系来评判应用的规模。我们将大规模应用定义为,需要众多开发者一同维护且具有一定复杂度的程序。
本书将会运用简单且易于理解的形式来介绍 TypeScript众多的特性。当你读完本书时,你应该知晓用 TypeScript构建大型 JavaScript应用所需的所有知识。本书不但提供了 TypeScript核心特性的介绍,还会带领你探索一些有用的工具、代码设计规则、昀佳实践以及如何将它们用于生产环境中。
本书涉及的内容
第 1章介绍了 TypeScript的核心特性,包括可选的静态类型提醒系统、操作符、函数、接口和模块。同时还附有在实际环境中使用它们的例子。
第 2章介绍了一些自动化工具,如 Gulp和 Karma,用以昀大化开发者的生产力。另外,本章还介绍了一些在开发 TypeScript应用时,有助于你使用第三方库的工具。
第 3章深入探讨了 TypeScript中的函数。为了成为一个精通 TypeScript的开发者,本章还会告诉你关于异步编程需要知晓的一些知识。
第 4章深入探讨 TypeScript中的面向对象编程,包含类、接口和模块,并且推荐了一些昀佳实践(SOLID原则1)。还会包括如继承、混入和泛型,它们都有助于增强代码的可复用性。
第 5章帮助你理解 TypeScript运行时的工作机制,将有助于避免一些潜在的性能问题,使得我们成为更高效的 TypeScript开发者。
第 6章讲解了高效运用可用的系统资源的必要知识。这一章还会阐述测试 TypeScript应用性能的方法,以及如何自动化一些用于提升 TypeScript应用性能的任务。
第 7章介绍了如何使用 TypeScript测试工具来进行 BDD(行为驱动开发)测试。在这一章,你将学习到如何使用 Karma、Mocha、Chai和 Sinon.JS来编写 TypeScript单元测试,如何使用 Nightwatch.js编写端对端测试,以及如何使用 Istanbul来生成测试覆盖率报告。
第 8章深入探讨了装饰器,包括类、属性、参数和方法装饰器。该章还会包括关于反射元数据 API 的介绍。
第 9章介绍了一些现代 Web应用的核心架构原则。该章会介绍单页面 Web应用的概念,以及它的通用组件和特性(模型、视图、控制器、路由和模板等)。该章还会通过实现一个单页面 Web应用框架,来阐述你所需知道的一切。
第 10章通过使用 TypeScript以及本书其他章节所提到的概念,来实现一个单页面 Web应用。
阅读本书前需要做的准备
本书中的例子都是使用 TypeScript 1.5编写的,你需要 TypeScript编译器和一个文本编辑器。本书将会说明如何使用 Atom,但是你也可以使用其他的编辑器,如 Visual Studio 2015、Visual Studio Code或 Sublime Text。
你还需要一个能够上网的环境来下载一些必要的依赖引用、包和库,如 jQuery、Mocha和 Gulp。在一些操作系统下安装本书中的一些工具,你可能还需要一个拥有管理员权限的账号。
本书的读者对象
如果你是一个想要学习 TypeScript来编写漂亮的 Web应用的中等水平的 JavaScript开发者,那么本书正适合你。你只需对 jQuery的基本概念有所了解。
为了让你能昀大化地运用 TypeScript语言和其编译器,本书将会由浅入深地介绍 TypeScript的语言结构和面向对象的特性。本书还将展示,如何使用强类型、面向对象的原则、设计模式和一些昀佳实践来轻松管理复杂的大规模 JavaScript应用。
约定惯例
本书将会使用不同的书写风格来区分不同种类的信息。以下是这些风格的例子和它们的意义。
正文中的代码、数据库表名、文件夹名、文件名、文件扩展名、路径名、 URL、用户输入和推特用户定位将会用代码体书写,如“我们可以通过 include指令将其他上下文包含进来”。
代码块则会是下面这样的风格:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting; } }
如果希望向你强调代码块中的一部分,那么它们将会以粗体展示:
function MathHelper() { /* ... */ }
// class methodMathHelper.areaOfCircle = function(radius) {return radius * radius * this.PI; }
// class property MathHelper.PI = 3.14159265359;
任何命令行的输入和输出将是以下这样的:
git clone https://github.com/user-name/repository-name.git
警告和关键提醒将会在这样的图标后出现。
小提示和小技巧将会在这样的图标后出现。
下载示例代码
你可以从 http://www.broadview.com.cn下载所有已购买的博文视点书籍的示例代码文件。
勘误表
虽然我们已经尽力谨慎地确保内容的准确性,但错误仍然存在。如果你发现了书中的错误,包括正文和代码中的错误,请告诉我们,我们会非常感激。这样,你不仅帮助了其他读者,也帮助我们改进后续的出版。如发现任何勘误,可以在博文视点网站相应图书的页面提交勘误信息。一旦你找到的错误被证实,你提交的信息就会被接受,我们的网站也会发布这些勘误信息。你可以随时浏览图书页面,查看已发布的勘误信息。
运算符 | 应该为 ||, 少了一个|
函数重载
function test(value:(string|number|boolean):string{
缺少了一个“)”
应为
function test(value:(string|number|boolean)):string{
var bat1 = new Bat();
应为
var bat1 = new Bat1();
I can fly! 后面多了一个引号