三斜线指令
三斜线指令是包含单个 XML
标记的单行注释,它们将作为编译指令,影响编译后的 .js
文件的输出内容。
随着模块标准的不断发展,三斜线指令如今已不再适用,无论是从代码管理还是从通用性的角度来说,模块都优于三斜线指令,因此不建议再使用三斜线指令。
但是,在实际项目中,你可能会遇到以往遗留的三斜线指令代码,所以仍需要了解三斜线指令的用法。本节将对三斜线指令做简要介绍。
引用其他文件
要引用其他文件,使用以下三斜线指令,示例代码如下。
/// <reference path ="引用文件路径"/>
假设 a.ts 文件的内容如下。
let a: number = 1;
假设 b.ts 文件的内容如下。
/// <reference path ="a.ts"/>
let b: boolean = true;
当执行 tsc b.ts
命令时,由于 b.ts
文件引用了 a.ts
文件,存在引用关系,因此虽然目标文件只有 b.ts
,但编译命令执行时会同时编译 a.ts
和 b.ts
文件,并同时输出 a.js
和 b.js
文件。
还可以使用 --outFile
选项指定输出文件路径及名称,例如,执行以下命令。
> tsc b.ts –outFile c.js
由于 b.ts
文件通过三斜线指令引用了 a.ts
文件,因此会将 a.ts
文件的代码同时包含在 b.ts
文件中,编译 b.ts
并输出 c.js
文件。c.js
文件的内容如下。
var a = 1;
/// <reference path ="a.ts"/>
var b = true;
指定包含在编译中的库文件
要指定包含在编译中的库文件,使用以下三斜线指令。
/// <reference lib="库名称" />
可选择库名称列表和 tsconfig.json
文件中的 lib
编译选项中可选择的名称列表相同。
例如,ECMAScript 2017 引入了字符串补全长度的功能,如果某个字符串没达到指定长度,会在头部或尾部补全。padStart()
用于头部补全,padEnd()
用于尾部补全。以下代码使用了 padEnd()
方法。如果编译选项中的 module
或 lib
使用了较早版本的 ECMAScript,则会引起编译错误。
var str: string = "hello";
//错误TS2550: 'string'不存在'padEnd'属性,是否应修改目标库?可尝试更改’lib’编译选项
//为’es2017’或之后的版本
str = str.padEnd(11, " world");
console.log(str);
此时,使用三斜线指令,指明编译该文件时使用的库文件,输出 JavaScript 时将按目标 ECMAScript 版本输出文件内容。
/// <reference lib="es2017.string" />
var str: string = "hello";
str = str.padEnd(11, " world");
console.log(str);
注意事项及其他指令
三斜线指令仅在其所在文件的顶部有效。该指令必须放在其他语句、声明、注释之前,否则将被视为普通单行注释,没有任何效果。示例代码如下。
let a: boolean = true;
/// <reference path ="a.ts"/>
let b: number = 1;
除上述指令之外,还有其他的三斜线指令,它们的应用场景较少,这里仅进行简单介绍。
/// <reference types="..." />
与 /// <reference path="…" /> 指令相似,/// <reference types="..." /> 指令是用来声明依赖的。 /// <reference types="…" /> 指令声明了对某个包的依赖。
对这些包的名字的解析与在 import
语句里对模块名的解析类似。可以简单地把三斜线类型引用指令当作 import
声明的包。
例如,把 /// <reference types="node" /> 引入声明文件,表明这个文件使用了 @types/node/index.d.ts
文件里声明的名字,并且这个包需要在编译阶段与声明文件一起包含进来。
/// <reference no-default-lib="true"/>
/// <reference no-default-lib="true"/> 指令把一个文件标记成默认库,通常会在 lib.d.ts
文件和类似文件的顶端看到该指令。
该指令指示编译器不在编译中包含默认库(即 lib.d.ts
文件)。这里的影响类似于在命令行上传递 –noLib
。
注意,当使用 --skipDefaultLibCheck
编译选项时,编译器将仅忽略检查带 ///<reference no-default-lib="true"/> 的文件。
/// <amd-module />
默认情况下,AMD 模块是匿名生成的。当使用其他工具处理编译后的模块文件时,这会导致问题。
amd-module
指令允许给编译器传入一个可选的模块名,示例 .ts
文件如下。
///<amd-module name='NamedModule'/>
export class C {}
当编译成 .js
文件后,会将 NamedModule
传入 AMD define 函数里,示例代码如下。
define("NamedModule", ["require" "exports"], function (require, exports) {
var C = (function () {
function C() {
}
return C;
})();
exports.C = C;
});
/// <amd-dependency />
/// <amd-dependency /> 指令已经废弃了,请使用 import "moduleName" 语句代替。
/// <amd-dependency path="x" /> 告诉编译器有一个非 TypeScript 模块依赖需要注入,它将作为目标模块 require
调用的一部分。
amd-dependency
指令也可以带一个可选的 name
属性,可以为 amd-dependency
传入一个可选名字,示例 .ts
文件如下。
/// <amd-dependency path="legacy/moduleA" name="moduleA"/>
declare var moduleA:MyType
moduleA.callStuff()
编译生成的 .js
文件如下。
define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) {
moduleA.callStuff()
});