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

289 Views Asked by At

This question is some what related to Why is typescript failing to import a module?, which I asked yesterday. The initial setup is the same.

I have a simple typescript file like this:

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

When I compile like so tsc --module commonjs file.ts, typescript is happy.

But, when I move the /// reference below the 'use strict', like this:

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

Typescript is not happy:

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

Typescript does indeed output a compiled file and it is the same as the one output originally, except of course that the /// reference is after 'use strict' in the second case.

What is happening here?

3

There are 3 best solutions below

1
Chara On BEST ANSWER

From MSDN,

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

This may be the reason.

0
MartyIX On

There is a note about <reference> tag in TypeScript 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.

1
Ryan Cavanaugh On

Reference directives have to be at the top of the file. When they're not at the top, they're ignored. This causes the module resolution to fail, because otherwise the compiler has no idea to go looking in some other random folder for the definition of the js-yaml module.

The reason for the restriction is simply performance: It's actually very slow (we tried!) to try to parse every single comment in a file to see if it's a reference directive or not.