
Angular是用一种类似于JavaScript的语言——TypeScript
——构建的。
或许你会对用新语言来开发Angular心存疑虑,但事实上,在开发Angular应用时,我们有充分的理由用TypeScript代替普通的JavaScript。
TypeScript并不是一门全新的语言,而是ES6的超集。所有的ES6代码都是完全有效且可编译的TypeScript代码。图2-1展示了它们之间的关系。

图2-1 ES5、ES6和TypeScript
什么是ES5?什么是ES6?ES5是ECMAScript
5的缩写,也被称为“普通的JavaScript”。ES5就是大家熟知的JavaScript,它能够运行在大部分浏览器上。ES6则是下一个版本的JavaScript,在后续章节中我们还会深入讨论它。
在本书出版的时候,支持ES6的浏览器还很少,更不用说TypeScript了。我们用转译器来解决这个问题。TypeScript转译器能把TypeScript代码转换为几乎所有浏览器都支持的ES5代码。

从TypeScript代码到ES5代码的唯一转换器是由TypeScript核心团队编写的。然而,将ES6代码(不是TypeScript代码)转换到ES5代码则有两个主要的转换器:Google开发的Traceur
与JavaScript社区创建的Babel
。在本书中我们并不会直接使用它们,但它们也是值得了解的不错项目。
我们在上一章安装了TypeScript环境,如果你是从本章开始学习的,那么可以这样安装TypeScript环境:npm install -g typescript。
TypeScript是Microsoft和Google之间的官方合作项目。有这两家强有力的科技巨头在背后支撑,对于我们来说是个好消息,因为这表示TypeScript将会得到长期的支持。这两家公司都承诺全力推动Web技术的发展,我们这些开发人员显然会获益匪浅。
另外,转译器的好处还在于:它允许小型团队对语言进行改善,而不必要求所有人都去升级他们的浏览器。
需要指出的是:TypeScript并不是开发Angular应用的必选语言。我们同样可以使用ES5代码(即“普通”JavaScript)来开发Angular应用。Angular也为全部功能提供了ES5 API。那么为什么我们还要使用TypeScript呢?这是因为TypeScript有不少强大的功能,能极大地简化开发。
TypeScript相对于ES5有五大改善:
●类型
●类
●注解
●模块导入
●语言工具包(比如,解构)
接下来我们逐个介绍。
顾名思义,相对于ES6,TypeScript最大的改善是增加了类型系统。
有些人可能会觉得,缺乏类型检查正是JavaScript这些弱类型语言的优点。也许你对类型检查心存疑虑,但我仍然鼓励你试一试。类型检查的好处有:
(1)有助于代码的编写,因为它可以在编译期预防bug;
(2)有助于代码的阅读,因为它能清晰地表明你的意图。
另外值得一提的是,TypeScript中的类型是可选的。如果希望写一些快速代码或功能原型,可以首先省略类型,然后再随着代码日趋成熟逐渐加上类型。
TypeScript的基本类型与我们平时所写JavaScript代码中用的隐式类型一样,包括字符串、数字、布尔值等。
直到ES5,我们都在用var关键字定义变量,比如var name;。
TypeScript的新语法是从ES5自然演化而来的,仍沿用var来定义变量,但现在可以同时为变量名提供可选的变量类型了:
var name:string;
在声明函数时,也可以为函数参数和返回值指定类型:
function greetText(name:string):string {
return "Hello " + name;
}
这个例子中,我们定义了一个名为greetText的新函数,它接收一个名为name的参数。name:string语法表示函数想要的name参数是string类型。如果给该函数传一个string以外的参数,代码将无法编译通过。对我们来说,这是好事,否则这段代码将会引入bug。
或许你还注意到了,greetText函数在括号后面还有一个新语法:string {。冒号之后指定的是该函数的返回值类型,在本例中为string。这很有用,原因有二:如果不小心让函数返回了一个非string型的返回值,编译器就会告诉我们这里有错误;使用该函数的开发人员也能很清晰地知道自己将会拿到什么类型的数据。
我们来看看如果写了不符合类型声明的代码会怎样:
function hello(name:string):string {
return 12;
}
当尝试编译代码时,将会得到下列错误:
$ tsc compile-error.ts
compile-error.ts(2,12):error TS2322:Type 'number' is not assignable to type 'string'.
这是怎么回事?我们尝试返回一个number类型的12,但hello函数期望的返回值类型为string(它是在参数声明的后面以):string {的形式声明的)。
要纠正它,可以把函数的返回值类型改为number:
function hello(name:string):number {
return 12;
}
虽然这只是一个小例子,但足以证明类型检查能为我们节省大量调试bug的时间。
现在知道了如何使用类型,但怎么才能知道有哪些可用类型呢?接下来我们就会罗列出这些内置的类型,并教你如何创建自己的类型。
尝试REPL
为了运行本章中的例子,我们要先安装一个小工具,名为TSUN
(TypeScript Upgraded Node,支持TypeScript的升级版Node):
$ npm install -g tsun
接着启动它:
$ tsun
TSUN:TypeScript Upgraded Node
type in TypeScript expression to evaluate
type:help for commands in repl
>
这个小小的>是一个命令提示符,表示TSUN已经准备好接收命令了。