javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > TypeScript 三斜线指令

TypeScript中三斜线指令的实现

作者:吴声子夜歌

本文主要介绍了TypeScript中三斜线指令的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

三斜线指令是一系列指令的统称,它是从TypeScript早期版本就开始支持的编译指令。目前,已经不推荐继续使用三斜线指令,因为可以使用模块来取代它的大部分功能。

正如其名,三斜线指令是以三条斜线开始,并包含一个XML标签。从JavaScript语法的角度上来看,三斜线指令相当于一条单行注释。若一个文件中使用了三斜线指令,那么在三斜线指令之前只允许使用单行注释、多行注释和其他三斜线指令。若某个三斜线指令出现在可执行语句之后,那么该三斜线指令将不生效。示例如下:

let count;

/// <reference path="lib.ts" />

count = add(1, 2);

此例第3行是一个三斜线指令,而第1行是一条变量声明语句,因此第3行的三斜线指令将不生效。下面将其修改为正确的使用方式,示例如下:

/// <reference path="lib.ts" />

let count = add(1, 2);

经过修改后,在第1行的三斜线指令之前没有可执行语句和声明,因此该三斜线指令会生效。

1、/// <reference path=“” />

该指令用于声明TypeScript源文件之间的依赖关系。在编译一个文件时,编译器会同时将该文件中使用“///<reference path=“” />”三斜线指令引用的文件添加到编译文件列表。

在“/// <reference path=“” />”三斜线指令中,​“path”属性定义了依赖文件的路径。若指定的路径是一个相对路径,则相对于的是当前文件的路径。

假设当前工程目录结构如下:

C:\app
|-- index.ts
`-- lib.ts

其中,​“index.ts”文件依赖于“lib.ts”文件。

“lib.ts”文件内容如下:

function add(x: number, y: number): number {
    return x + y;
}

“index.ts”文件内容如下:

/// <reference path="lib.ts" />

let count = add(1, 2);

在“C:\app”目录下运行tsc命令来编译“index.ts”文件。示例如下:

tsc index.ts

由于“index.ts”文件依赖于“lib.ts”文件,所以在编译“index.ts”文件时,编译器不但会将“index.ts”文件添加到编译文件列表,还会将“lib.ts”文件添加到编译文件列表。

此时,​“C:\app”目录的结构如下:

C:\app
|-- index.js
|-- index.ts
|-- lib.js
`-- lib.ts

1.1、–outFile编译选项

使用“–outFile”编译选项能够将编译生成的“.js”文件合并为一个文件。但需要注意的是,该编译选项不支持合并使用了CommonJS模块和ES6模块模式的代码,只有将“–module”编译选项设置为None、System或AMD时才有效。

在合并生成代码的过程中,​“/// <reference path=“”/>”三斜线指令可以作为排序文件的一种手段。

假设当前工程目录结构如下:

C:\app
|-- index.ts
|-- lib1.ts
`-- lib2.ts

“lib1.ts”文件的内容如下:

const a = 'lib1';

“lib2.ts”文件的内容如下:

const b = 'lib2';

“index.ts”文件的内容如下:

/// <reference path="lib2.ts" />
/// <reference path="lib1.ts" />

const index = 'index';

在“C:\app”目录下运行tsc命令来编译“index.ts”文件,并将编译后的文件合并为“main.js”​。示例如下:

tsc index.ts --outFile main.js

合并后的“main.js”文件内容如下:

var b = 'lib2';
var a = 'lib1';
/// <reference path="lib2.ts" />
/// <reference path="lib1.ts" />
var index = 'index';

在“index.ts”文件中,我们先声明了对“lib2.ts”文件的依赖,后声明了对“lib1.ts”文件的依赖。在合并后的文件中,​“lib2.ts”文件内容将出现在“lib1.ts”文件内容之上,在最后的是“index.ts”文件的内容。

1.2、–noResolve编译选项

在默认情况下,编译器会检查三斜线指令中引用的文件是否存在,并将它们添加到编译文件列表。若启用了“–noResolve”编译选项,则编译器将忽略所有的三斜线指令。此时,三斜线指令中引用的文件既不会被添加到编译文件列表,也不会影响“–outFile”的结果。

假设当前工程目录结构如下:

C:\app
|-- index.ts
|-- lib1.ts
`-- lib2.ts

“lib1.ts”文件的内容如下:

const a = 'lib1';

“lib2.ts”文件的内容如下:

const b = 'lib2';

“index.ts”文件的内容如下:

/// <reference path="lib2.ts" />
/// <reference path="lib1.ts" />

const index = 'index';

在“C:\app”目录下运行tsc命令来编译“index.ts”文件,同时将编译后的文件合并为“main.js”​,并启用“–noResolve”编译选项。示例如下:

tsc index.ts --outFile main.js --noResolve

合并后的“main.js”文件内容如下:

/// <reference path="lib2.ts" />
/// <reference path="lib1.ts" />
var index = 'index';

通过以上运行结果能够看到,三斜线指令中引用的“lib1.ts”和“lib2.ts”文件在编译过程中被忽略了

1.3、 注意事项

在使用“/// <reference path=“” />”三斜线指令时,有以下两个注意事项:

例如,如下的“index.ts”文件中两处对三斜线指令的使用均有错误:

/// <reference path="unknown.ts" />
//                   ~~~~~~~~~~
//                   编译错误:文件未找到
/// <reference path="index.ts" />
//                   ~~~~~~~~~~
//                   编译错误:文件不能引用自身

2、/// <reference types=“” />

该三斜线指令用来定义对某个DefinitelyTyped声明文件的依赖,或者说是对安装在“node_modules/@types”目录下的某个声明文件的依赖。在“/// <reference types=“”/>”三斜线指令中,​“types”属性的值是声明文件安装包的名称,也就是安装到“node_modules/@types”目录下的文件夹的名字。

例如,我们使用如下命令安装了DefinitelyTyped提供的jQuery声明文件:

npm install @types/jquery

在安装后,工程目录结构如下:

C:\lib
|-- index.d.ts
`-- node_modules
    `-- @types
        `-- jquery
            |-- index.d.ts
            `-- package.json

jQuery声明文件被安装在了“C:\lib\node_modules@types\jquery”目录下。因此,​“jquery”这个名字就是可以在“/// <referencetypes=“” />”三斜线指令中使用的名字。

“C:\lib\index.d.ts”文件的内容如下:

/// <reference types="jquery" />

declare var settings: JQuery.AjaxSettings;

注意,我们应该只在声明文件(.d.ts)中使用“/// <reference types=“” />”三斜线指令,而不应该在“.ts”文件中使用该指令。在.ts文件中,我们应该使用“–types”编译选项和“–typeRoots”编译选项来设置引用的声明文件。

3、/// <reference lib=“” />

该三斜线指令用于定义对语言内置的某个声明文件的依赖。在前文介绍过,当我们在计算机中安装TypeScript语言时,也会同时安装一些内置的声明文件。这些声明文件位于TypeScript安装目录下的lib文件夹中,它们描述了JavaScript语言的标准API。内置的声明文件列表如下:

lib.d.ts                              lib.es2018.full.d.ts
lib.dom.d.ts                          lib.es2018.intl.d.ts
lib.dom.iterable.d.ts                 lib.es2018.promise.d.ts
lib.es2015.collection.d.ts            lib.es2018.regexp.d.ts
lib.es2015.core.d.ts                  lib.es2019.array.d.ts
lib.es2015.d.ts                       lib.es2019.d.ts
lib.es2015.generator.d.ts             lib.es2019.full.d.ts
lib.es2015.iterable.d.ts              lib.es2019.object.d.ts
lib.es2015.promise.d.ts               lib.es2019.string.d.ts
lib.es2015.proxy.d.ts                 lib.es2019.symbol.d.ts
lib.es2015.reflect.d.ts               lib.es2020.d.ts
lib.es2015.symbol.d.ts                lib.es2020.full.d.ts
lib.es2015.symbol.wellknown.d.ts      lib.es2020.string.d.ts
lib.es2016.array.include.d.ts         lib.es2020.symbol.wellknown.d.ts
lib.es2016.d.ts                       lib.es5.d.ts
lib.es2016.full.d.ts                  lib.es6.d.ts
lib.es2017.d.ts                       lib.esnext.array.d.ts
lib.es2017.full.d.ts                  lib.esnext.asynciterable.d.ts
lib.es2017.intl.d.ts                  lib.esnext.bigint.d.ts
lib.es2017.object.d.ts                lib.esnext.d.ts
lib.es2017.sharedmemory.d.ts          lib.esnext.full.d.ts
lib.es2017.string.d.ts                lib.esnext.intl.d.ts
lib.es2017.typedarrays.d.ts           lib.esnext.symbol.d.ts
lib.es2018.asyncgenerator.d.ts        lib.scripthost.d.ts
lib.es2018.asynciterable.d.ts         lib.webworker.d.ts
lib.es2018.d.ts                       lib.webworker.importscripts.d.ts

该列表并不是固定的,它会随着TypeScript版本的升级而更新。

在“/// <reference lib=“” />”三斜线指令中,​“lib”属性的值是内置声明文件的名称。内置声明文件统一使用“lib.[description].d.ts”命名方式,而“/// ”指令中“lib”属性的值就是文件名中的“description”这部分

例如,对于内置的“lib.es2015.symbol.wellknown.d.ts”声明文件,应使用如下方式进行引用:

/// <reference lib="es2015.symbol.wellknown" />

3.1、–target编译选项

“–target”编译选项能够设置程序的目标运行环境,可选择的值为:

如果我们将“–target”编译选项设置为“ES5”​,那么编译器会自动将适用于“ES5”的内置声明文件添加到编译文件列表。示例如下:

lib.d.ts
lib.es5.d.ts
lib.dom.d.ts
lib.webworker.importscripts.d.ts
lib.scripthost.d.ts

另外,​“–target”编译选项还决定了对哪些语法进行降级处理。例如,在“ES5”环境中不支持箭头函数语法,因此当将“–target”设置为“ES5”时,编译后代码中的箭头函数将被替换为“ES5”环境中支持的函数表达式。

假设“index.ts”文件的内容如下:

const double = [0, 1, 2].map(val => val * 2);

将“–target”设置为“ES5”​,然后编译“index.ts”文件的结果如下:

var double = [0, 1, 2].map(function (val) {
    return val * 2;
});

此例中,箭头函数被降级成了常规的函数表达式。

将“–target”设置为“ES6”​,编译“index.ts”文件的结果如下:

const double = [0, 1, 2].map(val => val * 2);

此例中,箭头函数没有被降级,因为在“ES6”环境中支持箭头函数这个功能。

3.2、–lib编译选项

“–lib”编译选项与“/// <reference lib=“” />”三斜线指令有着相同的作用,都是用来引用语言内置的某个声明文件。

如果将“–target”设置为“ES6”​,但是我们想使用ES2017环境中才开始支持的“pad-Start()”函数。那么,我们就需要引用内置的“lib.es2017.string.d.ts”声明文件,否则编译器将产生编译错误。

在“tsconfig.json”配置文件中使用“–lib”编译选项,示例如下:

{
    "compilerOptions": {
        "target": "ES6",
        "lib": ["ES6", "ES2017.String"]
    }
}

注意,我们不但要传入“ES2017.String”​,还要传入“ES6”​,否则编译器将仅包含“ES2017.String”这一个内置声明文件,这通常不是我们期望的结果。

使用“/// <reference lib=“” />”三斜线指令,示例如下:

/// <reference lib="ES2017.String" />

不论使用以上哪种方式,我们都可以在代码中使用“padStart()”函数,因为编译器能够获取到该函数的类型信息。示例如下:

'foo'.padStart(10, '-');

需要注意的是,在将“lib.es2017.string.d.ts”内置声明文件添加到编译文件列表后,虽然编译器允许使用“padStart()”方法,但是实际的JavaScript运行环境可能不支持该方法。因为该方法是在ES2017标准中定义的,而JavaScript运行环境可能仍处于一个较旧的版本,因此不支持这个新方法。这样就会导致程序可以成功地编译,但是在运行时出错,因为找不到“padStart()”方法的定义。

在实际项目中,我们通过引入“polyfill”脚本来解决这个常见问题。​“polyfill”已经成为了Web开发领域中的一个术语,在很多地方它被叫作“腻子脚本”​,个人感觉叫作“填充脚本”可能容易理解。​“polyfill”脚本是一段JavaScript代码,它使用普遍支持的Java-Script语法和API来实现新版本JavaScript中才支持的API(在新版本ECMAScript规范中定义的API)​。因此,它相当于用自定义代码来填充JavaScript运行环境中缺失的API,从而为JavaScript运行环境打上了“补丁”​。

到此这篇关于TypeScript中三斜线指令的实现的文章就介绍到这了,更多相关TypeScript 三斜线指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文