为什么当 /// 引用在 'use strict' 之后时打字稿会报错?

Why is typescript complaining when a /// reference is after 'use strict'?

这个问题和我昨天问的有关。初始设置相同。

我有一个像这样的简单打字稿文件:

/// <reference path="./typings/js-yaml/js-yaml.d.ts"/>
'use strict';
import * as y from 'js-yaml';
console.log(y);

当我这样编译时tsc --module commonjs file.ts,打字稿很开心。

但是,当我将 /// 引用移动到 'use strict' 下方时,如下所示:

'use strict';
/// <reference path="./typings/js-yaml/js-yaml.d.ts"/>
import * as y from 'js-yaml';
console.log(y);

打字稿不开心:

$ tsc --module commonjs file.ts 
file.ts(4,20): error TS2307: Cannot find module 'js-yaml'.

Typescript 确实输出了一个编译后的文件,它与最初的输出相同,当然除了在第二种情况下 /// 引用在 'use strict' 之后。

这里发生了什么?

来自 MSDN

The following rules apply to a reference directive. The reference XML comment must be declared before any script.

可能是这个原因。

TypeScript 中有关于 <reference> 标签的说明 specification:

A comment of the form /// <reference path="…"/> that occurs before the first token in a source file adds a dependency on the source file specified in the path argument. The path is resolved relative to the directory of the containing source file.

参考指令必须位于文件顶部。当它们不在顶部时,它们就会被忽略。这会导致模块解析失败,否则编译器无法在其他随机文件夹中查找 js-yaml 模块的定义。

限制的原因很简单:它实际上非常慢(我们试过了!)试图解析文件中的每条注释以查看它是否是引用指令。