TypeScript基本介绍及环境配置


         TypeScript由微软构建,旨在帮助开发人员更轻松地构建大型前端应用程序。它是JavaScript的超集,为它带来了丰富的类型系统,这种类型系统可以帮助开发人员更早的发现错误,并允许可靠地创建工具浏览和重构代码。

目录

TypeScript文档... 1

安装... 1

TypeScript的好处... 1

基本类型... 1

关键字... 2

接口(Interfaces)... 2

类(class)... 2

模块(modules) 2

模块格式... 3

Exporting. 3

Importing. 3

Default exports. 3

配置编译... 3

--target. 4

--outDir. 4

--module. 4

--allowJS. 4

--watch. 5

--noImplicitAny. 5

--noImplicitReturns. 5

--sourceMap. 6

--moduleResolution. 6

Tsconfig.json. 6

介绍... 6

指定需要编译的文件... 7

TypeScript linting. 8

Installing TSLint. 8

Configuring rules. 8

Built-in rules. 10

Excluding Files. 11

Code formatting. 11

摘要... 11

安装

  1. 安装Google Chrome浏览器。
  2. 安装jsnpm
  3. 安装TypeScript,可以在命令行输入 npm install –g typescript进行安装。
  4. 安装Visual Studio Code

TypeScript的好处

  1. JavaScript代码库增长时,它变得难以阅读与维护。TypeScriptJavaScript的扩展,并添加了静态类型。TypeScript编译器读取TypeScript包含类型信息的代码,并使用该类型生成清晰易读的JavaScript代码。编译后的代码可以浏览器和js中运行。
  2. JavaScript相比,TypeScript具有多个有点:

基本类型

Type

Description

string

表示Unicode字符序列。

number

表示整数和浮点数。

boolean

表示truefalse

undefined

表示一个尚未初始化的值。

null

表示没有值。


关键字

Key word

Description

Any

 

Void

 

Never

 

Enum

 

Object

 

Array

 

接口(Interfaces

         接口是一种契约,它定义了带有属性和方法定义的集合的类型,而没有任何实现。JavaScript中不存在接口,因此TypeScript编译器仅适用它们通过类型检查来实施契约。

         我们使用interface关键字创建一个接口,其后是接口名称,然后是用花括号组成的内容。

         Interface Project{

……..

}

类(class

         类具有许多编程语言的功能,包括JavaScript。它们使我们能够以接口与类型别名类似的方式对带有类型注释的对象进行使用。然后,类具有比接口和类型别名更多的功能。

Class Project{

…..

}

模块(modules)

         默认情况下,TypeScript生成的JavaScript代码在全局范围内执行。这意味着一个文件中代码将自动在另一个文件中可以使用。然而,这意味着如果名称相同,我们实现的功能可以覆盖其他文件中的功能,这将导致我们的应用程序会中段,即运行失败。

         在全局范围内操作存在问题,因为项目名称可能会在不同的文件直接发生冲突,并且随着我们的代码库的增长,这很难避免。模块解决了这个问题,并帮助我们编写了组织良好且可重用的代码。

模块格式    

         JavaScript中的模块功能是ES6的一部分。但是,在此标准化之前,其他流行的模块格式中也存在许多代码。TypeScript允许我们使用ES6模块编写代码,然后可以将其转换为另一种模块格式。

         以下是TypeScript可以转换为不同模块格式的简要说明:

AMD(Asynchronous Module Definition):这通常在针对浏览器的代码中使用,并使用define函数定义模块。

CommonJS:Node.js程序中使用此格式。其使用module.exports定义模块并需要定义依赖项。

UMD(Universal Module Definition):这可以在浏览器应用程序和Node.js应用程序中使用。

ES6:这是本机JavaScript模块格式,使用export关键字定义模块并使用import定义依赖项。

Exporting

         从模块中导出的代码可以被其他模块使用。为了从模块中导出代码,我们使用export关键字。我们可以指定在定义项目之前直接使用export导出接口,别名,函数,常量等。

Importing

         导入可以使我们从导出的模块中导入代码。我们使用导入语句来执行此操作,该语句包括要使用大括号导入的项目名称和从中获取项目的文件路径(不包括ts扩展名)。我们只能导入在其他模块文件中导出的项目。

Default exports

         我们可以指定一个默认情况下使用default关键字导出的项目:

         Export default interface{

         Name:string;

         unitPrice:number;

}

         注意,我们不需要命名接口,然后可以导入默认导出的项目,而无需使用花括号来选择我们所需要的名称。

         Import poduct from “./product”;

配置编译

         我们需要先编译我们的TypeScript代码,然后才能在浏览器中执行。为此,我们在要编译的文件上运行TypeSctipttsc

TypeScript很流行,可以应用许多不同的情况:

  1. 通常将其引入现有的大型JavaScript代码库中。
  2. 默认情况下,应用在Angular项目中。
  3. 通常用于向React项目中添加强类型。
  4. 其也可以在js项目中使用。

所有这些情况对TypeScript编译器的要求都稍有不同。所以,编译器为我们提供了不同的选项,以满足我们对特定情况的要求。

所有的编译配置都可以在https:/​/​www.​typescriptlang.​org/​docs/handbook/​compiler-​options.​html中找到。

以下列出经常使用的一些配置选项:

--target

         这确定了将在其中生成编译代码的ECMAScript版本。默认值是ES3,它将确保代码可以在各种浏览器使用的不同版本。但是,此编译目标将生成最多的代码,因为编译器将为ES3中不支持的功能生成polyfill代码。ESNext选项是另一个极端,它可以编译为最新支持的建议ES功能。这将生成最少的代码,但仅在浏览器上有效实现了我们所使用的功能。

         作为例子:tsc orderDetail –target es6

--outDir

         默认情况下,已转译的JavaScript文件与TypeScript文件位于同一个目录中。--outDir可用于将这些文件放置在其他目录中。

         让我们尝试一下,然后将转译的orderDetail.js输出到名为dist的文件夹中。

         让我们在终端中输入一下内容:

         Tsc orderDetail –outDir dist

         将创建一个dist文件夹,其中包含生成的orderDetail.js文件。

--module

                   这指定了生成的JavaScript应该使用的模块格式。默认实以ES3ES5为目标的CommonJS模块格式。目前,在创建新项目时,ES6ESNext是常用选项。

--allowJS

         此选项告诉TypeScript编译器处理JavaScript文件以及TypeScript文件。如果我们已经用JavaScript编写了一些代码并且使用了尚未在所有浏览器中实现的功能,这将非常有用。这种情况下,我们可以使用TypeScript编译器将JavaScript转换为可以在广泛的浏览器中使用的代码。

--watch

         此选项使TypeScript编译器无限期运行。每当更改源文件时,都会自动触发编译过程以生成新版本。这是在开发过程中开启的有用选项:

  1. 让我们在终端中输入一下内容进行尝试:

tsc  orderDetail  --watch

  1. 编译器应运行,并在完成后给出消息watching for 2.file changes。让我们更改OrderDetail类中的getTotal方法。以便处理未定义折扣的情况:

GetTotal(discount:number):number{

}

  1. 当我们保存ts时,编译器会提示检测到File change 3。开始增量编译并执行编译。

要退出监视模式,我们可以通过单击终端的bin图表来终止终端。

--noImplicitAny

         这强制我们明确指定要使用它的任何类型,同时也强制我们考虑使用任何一种类型以及是否真的需要它。

让我们看下下面的例子:

  1. OrderDetail类中添加一个doSomething方法,该方法具有一个没有类型标注的输入参数。

Export class OrderDetail{

doSomething(input){

}

}

  1. 让我们在终端使用—noImplicitAny标志进行编译:

Tsc orderDetail –noImplicitAny

编译器输出一下错误信息,因为我们没有明确说明输入参数的类型:

orderDetail.ts(14,15): error TS7006: Parameter 'input' implicitly has an 'any' type.

  1. 我们可以通过添加带有类型标注来解决此问题。

Export class OrderDetail{

doSomething(inputnumber){

}

}

         如果我们再次使用—noImplicitAny进行编译,则编译顺利通过。

--noImplicitReturns

         如果返回类型不是void,这可以确保我们在函数的所有分支中返回值。

如下所示:

  1. 在我们的Orderdetail类中,假如我们有getTotal方法的实现。

getTotal(discount:number):number{

if (discount){

return 0.5 * discount;

}else{

//we forgot about this branch!

}

}

  1. 我们忘记顺利实现else分支的返回值,如果我们不适用—noImplicitReturns编译标志,其可以正常编译。

Tsc  orderDetail

  1. 但是,让我们看看如果使用noImplicitReturns flag

Tsc  orderDetail  --noImplicitReturns

正如预期的那样,我们收到以下错误。

orderDetail.ts(9,31): error TS7030: Not all code paths return a value.

--sourceMap

       如果设置此选项,在编译过程中会生成*.map文件。这将使我们能够调试程序的TypeScript版本(而不是转译的JavaScript)。因此,通常在开发过程中将其打开。

--moduleResolution

         这告诉TypeScript编译器如何解析模块。这可以将其设置为classic或者node。如果使用的是ES6模块,则默认为classic,这意味着TypeScript编译器很难找到第三方软件包,例如Axios,因此,我们可以显示设置到节点,以告诉编译器在“node_modules”中查找模块。

Tsconfig.json

介绍

         正如我们所看到的,我们可以将许多不同的开关应用于编译过程,并且在命令行上重复指定这些开关有些笨拙。幸运的是,我们可以在名为tsconfig.json的文件中指定这些选项。我们拥有的编译器选项在上一节中介绍的内容是在没有”—“前缀的compileOptions字段中定义的。

如下所示:

让我们创建一个具有以下内容的tsconfig.json文件:

{

"compilerOptions": {

"target": "esnext",

"outDir": "dist",

"module": "es6",

"moduleResolution": "node",

"sourceMap": true,

"noImplicitReturns": true,

"noImplicitAny": true

}

}

2. 让我们运行编译而不指定源文件和任何标志。

           tsc

           编译将运行良好,将已编译的JavaScript与源映射文件一起输出到dist文件夹。

指定需要编译的文件

         有几种方法可以告诉TypeScript编译器处理那些文件。最简单的方法是在文件字段中明确列出文件:

{

         “compilerOptions”:{

                   ….

}

“files”:[“product.ts”,”orderDetail.ts”]

}

         但是,随着代码库的增长,这种方法很难维护。一种更易于维护的方法是使用includeexclude字段定义需要包含和排除的文件模式。

         下面的实例查看这些字段的具体用法:

  1. 让我们添加一下字段,这些字段告诉编译器编译src文件夹及其子文件夹内的TypeScript文件:

{

“compilerOptions”:{

           ….

}

“include”:[“src/**/*”]

}

  1. 现在,我们的源文件不在src文件夹中,但是无论如何,让我们运行编译:

tsc

  1. 不出所料,我们在配置文件中没有找到编译器需要编译的文件。

让我们创建一个src文件夹并将orderDetail.ts移到该文件夹中。如果再次进行编译,它将成功找到文件并进行编译。

           因此,我们有很多选择可以使TypeScript编译器适应我们的特定情况。

一些选项(例如--noImplicitAny)强制我们编写良好的TypeScript代码。通过将linting引入我们的项目中,我们可以将代码检查提高到一个新的水平。

TypeScript linting

         如我们所见,编译器对我们的TypeScript代码进行了许多有用的检查,以帮助我们编写无错误的代码。我们可以更进一步,使代码更加整洁,以帮助我们使代码更具有可读性和可维护性。TSLint是在TypeScript项目中非常流行的linter

         TSLint的主页位于https:/​/​palantir.​github.​io/​tslint/

Installing TSLint

         安装TSLint以及一个Visual Studio Code扩展,它将在代码中突出显示出有问题的代码。

  1. 通过npm全局安装TSLint,如下所示:

Npm install –g tslint

  1. 现在,我们可以打开Visual Studio Code并转到扩展区域(Ctrl +Shift+X),然后在左上角的搜索框中输入tslint,该扩展名为TSLint,egamma发布:
  2. 我们需要单击安装选项来安装扩展。
  3. 安装完成后,我们需要重新加载Visual Studio Code才能启动该扩展。

已经安装了此扩展程序以及全局范围内的STLint,则将在我们的代码中突出显示代码错误。

Configuring rules

         Tslint在检查代码时使用的规则可言在名为tslint.json的文件中进行配置。为了使用这些规则,首先需要个TypeScript文件。

  1. Visual Studio Code中创建一个名为ts的文件,其中包含以下内容:
  2. 现在让我们创建一个json文件,我们在规则字段中定义要实施的规则,添加一下规则:
  3. 规则的完整列表可以在一下网址找到:https:///palantir.github.io/tslint/rules/.

成员访问规则强制我们明确声明访问类的修饰符。我们尚未在OrderDetail类中显示定义属性和方法访问修饰符,因为默认情况下它们使公共的,因此,有了插入规则,Visual Studio Code将向我们强调缺少访问修饰符:

  1. 当我们在属性和方法前面放置一个公共访问修饰符时,警告消失了。

           成员访问规则强制我们编写更多代码,这怎么可能是一件好事?如果你正在阅读代码并且对TypeScript的了解不够深,以至于没有访问修饰符的类成员是公共的,该规则很有用。因此,如果团队由不太了解TypeScript的开发人员组成,则很适用。但是,不一定适合经验丰富的TypeScript开发人员团队。许多的tslint规则例如member-access,它们会运作良好,而在其他团队中,它们并没有真正增加价值,这就是为什么规则是可配置的。

Built-in rules

         Tslint拥有一组方便使用的内置规则。我们可以通过在extends字段中指定规则集名称来使用它们。我们可以通过将所有规则集的名称放入数组来使用多个规则集:

  1. 让我们采用tslint附带的经过慎重考虑的一组规则,称为”tslint:recommended”。因此,在我们的json文件中,我们删除规则字段并添加扩展字段,如下所示:

保存tslint时,立刻获得lint错误,错误是抱怨Product接口缺少前缀。该规则背后的逻辑是,在读取代码时,如果类型以I开头,我们会立刻知道它是一个接口。

  1. 让我们假装该规则对我们没有价值,我们可以在”rules”字段中的”tslint:recommended”覆盖此规则。该规则称为”interface-name”,因此,我们将其覆盖为false:

         保存tslint.json后,警告错误立即消失。

Excluding Files

         我们可以从linting过程中排除文件,这对于排除第三方代码很有用,我们可以通过在linterOptions字段的exclude字段中指定文件数组来实现:  

         前面的配置从linting过程中排除了第三方节点程序包。

Code formatting

         Visual Studio Code中安装另一个扩展名为Prettier的插件,它将自动格式化我们的代码。出来有助于修正代码的样式,还有助于我们遵守某些TSLint规则:

  1. 打开Visual Studio代码,转到“扩展”区域,然后在搜索框中键入prettier,该扩展名为Prettier-Code formatter,由Esben Petersen发布:
  2. 需要单击安装选项以安装扩展。
  3. 安装完成后,需要重新加载Visual Studio Code才能启动该扩展。
  4. 最后一步是确保在用户设置中选中保存时格式化选项。按Ctrl+,(逗号)打开设置屏幕,然后在搜索框中键入保存时格式化以查找设置。如果未勾选设置,请勾选。

现在已经安装了此扩展,当我们保存TypeScript代码时,将自动为我们很好的格式化它。

摘要

         本文首先介绍了我们为什么要使用TypeScript构建前端。现在,我们拥有了TypeScript的第一手经验,可以及早发现错误并未我们提供诸如IntellISense之类的生产力功能。我们了解到TypeScript只是JavaScript的扩展。因此,我们可以使用JavaScript中的所有功能以及TypeScript的其他功能。这些附加的功能之一是类型注释,它可以帮助编译器发现错误并点亮功能,例如在代码编辑器中进行代码导航。

         我们没有涉及类型的所有内容。但是,现在有足够的知识来构建相当复杂的TypeScript程序。尤其是类,使我们能够很好地队复杂现实世界对象进行建模。我们了解了模块以及它们如何使我们脱离危险的全局。模块使我们能够很好的构建代码并使代码可重用。

         我们了解到了有关TypeScript编译器的知识,以及它在不同用例中如何能很好地工作,这是因为它非常易于配置。这在TypeScriptReact一起使用时,也非常重要。

         TSLintPrettier是锦上添花。这两个工具的好处是它们可以我们的代码库中保持一致性,从而使代码更具有可读性。