TypeScript Handbook を読む (21. Triple-Slash Directives)

[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) を読み進めていく第二十一回目。

1. [Basic Types](http://qiita.com/murank/items/9c1f633545842c953947)
1. [Variable Declarations](http://qiita.com/murank/items/913f1c1e4e725047436c)
1. [Interfaces](http://qiita.com/murank/items/553276c3dc2eec9bfe47)
1. [Classes](http://qiita.com/murank/items/7e8f15225bc8259e9bf3)
1. [Functions](http://qiita.com/murank/items/e310ce68ed5a0058d42d)
1. [Generics](http://qiita.com/murank/items/144b686d34fd433a97a3)
1. [Enums](http://qiita.com/murank/items/cc487562b21bae3728ba)
1. [Type Inference](http://qiita.com/murank/items/e67ad7426020321228e9)
1. [Type Compatibility](http://qiita.com/murank/items/e06efb0615294a6826e3)
1. [Advanced Types](http://qiita.com/murank/items/bc1776efbecbd2120d94)
1. [Symbols](http://qiita.com/murank/items/04b3b31caa677750f240)
1. [Iterators and Generators](http://qiita.com/murank/items/7ceec53dde886f31a682)
1. [Modules](http://qiita.com/murank/items/0fc4e059be8ea5e1c274)
1. [Namwspaces](http://qiita.com/murank/items/0dfad4a0bb91aaa6c97b)
1. [Namespaces and Modules](http://qiita.com/murank/items/0be1978a3515fc76e7ba)
1. [Module Resolution](http://qiita.com/murank/items/5f11466474d49498bbd5)
1. [Declaration Merging](http://qiita.com/murank/items/ec90ba04edab1ea3718e)
1. [JSX](http://qiita.com/murank/items/90164aa9a3bed3c49a80)
1. [Decorators](http://qiita.com/murank/items/580e34883e0832ca7aed)
1. [Mixins](http://qiita.com/murank/items/e77ad8359ed1fd82822d)
1. Triple-Slash Directives (今ココ)
1. [Type Checking JavaScript Files](https://qiita.com/murank/items/588eaddfe8af59914658)


# Triple-Slash Directives
[原文](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html)

トリプルスラッシュ・ディレクティブは単一の XML タグを含む単一行コメントで、コメントの内容はコンパイラディレクティブとして使用されます。

トリプルスラッシュ・ディレクティブはファイルの先頭で使用された場合 **のみ** 有効です。
また、トリプルスラッシュ・ディレクティブの前には他のトリプルスラッシュ・ディレクティブを含む、単一行または複数行コメントのみを配置できます。
もしトリプルスラッシュ・ディレクティブが命令文または宣言の後に配置された場合、それは通常のコメントとして扱われ、特別な意味を持たなくなります。

## `/// <reference path="..." />`
`/// <reference path="..." />` ディレクティブはもっとも一般的なディレクティブで、ファイル間の *依存関係* を宣言するために使用されます。

トリブルスラッシュ参照はコンパイル時に追加のファイルをインクルードするようコンパイラに伝えます。

また、このディレクティブは `--out` または `--outFile` を使用した時の出力順を決定するためにも使用されます。
前処理を行った後の入力ファイルと同じ順番で出力先に書き込まれます。

### Preprocessing input files
すべてのトリプルスラッシュ参照ディレクティブを解決するために、コンパイラは入力ファイルに対して前処理を行います。
この処理の中で追加するファイルがコンパイル対象に含まれるようになります。

前処理はルートファイル (コマンドライン、または `tsconfig.json` の `"files"` で指定したファイル) から開始されます。
この時、ルートファイルはそれが指定された順で処理されます。
ファイル自身がコンパイル対象に追加される前に、トリプルスラッシュ参照の参照先がコンパイル対象に追加されます。つまり、トリプルスラッシュ参照は深さ優先で解決されるということです。

トリプルスラッシュ参照が非相対パスで指定されている場合、そのファイルからの相対パスとして扱われます。

### Errors
参照先のファイルが存在しない場合はエラーとなります。また、自分自身へのトリプルスラッシュ参照もエラーとなります。

### Using `--noResolve`
コンパイラオプションの `--noResolve` が指定された場合、トリプルスラッシュ参照は無視されます。つまり、新しいファイルがコンパイル対象になることもありませんし、ファイルの出力順も変更されません。


## `/// <reference types="..." />`
`/// <reference path="..." />` ディレクティブと同様に、このディレクティブも *依存関係* を宣言するものです。
ただし、`/// <reference types="..." />` ディレクティブはパッケージへの依存関係を宣言します。

パッケージ名の解決プロセスは `import` 文に対するモジュール名の解決プロセスと似ています。
つまり、トリプルスラッシュ型参照は宣言パッケージに対する `import` と考えてもらって構いません。

例として、宣言ファイルに `/// <reference types="node" /> ` を含んでいた場合、このファイルでは `@types/node/index.d.ts` で宣言されている名前を使用することを表しています。
そのため、この宣言ファイルをコンパイルする際にこのパッケージをインクルードする必要があります。

このディレクティブは手作業で `d.ts` ファイルを作成する場合にだけ使用してください。

コンパイル時に生成される宣言ファイルには、コンパイラが自動的に `/// <reference types="..." />` を追加します。
ただし、`/// <reference types="..." />` は
参照先のパッケージ内の宣言を使用している場合のみ、追加されます。

`.ts` ファイルで `@types` パッケージに対する依存関係を宣言する場合、代わりにコマンドラインか `tsconfig.json` で `--types` を使用してください。
詳しくは [using `@types`, `typeRoots` and `types` in `tsconfig.json` files](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types) を参照してください。


## `/// <reference lib="..." />`

このディレクティブを使うと既存の組み込み *lib* ファイルを明示的にインクルードすることができます。

組み込み *lib* ファイルは *tsconfig.json* の `"lib"` オプションと同じ方法で参照されます。(例: `lib="lib.es2015.d.ts"` ではなく `lib="es2015"` と指定してください)

組み込み型 (DOM API や `Symbol`、`Iterator` のような組み込み実行時コンストラクタなど) に依存する宣言ファイルを作成している場合、lib ディレクティブを使用することを推奨します。

例えば、あるファイルに `/// <reference lib="es2017.string" />` を追加した場合、`--lib es2017.string` を指定してコンパイルした場合と同じになります。

```ts:TypeScript
/// <reference lib="es2017.string" />
"foo".padStart(4);
```

## `/// <reference no-default-lib="true"/>`
このディレクティブはファイルを *標準ライブラリ* としてマークします。
おそらく `lib.d.ts` ファイルの先頭でこのコメントを目にすることでしょう。

このディレクティブを使用するとコンパイル時に標準ライブラリ (`lib.d.ts`) がインクルードされなくなります。
この挙動は `--noLib` コマンドラインオプションを指定した場合と似ています。

また、`--skipDefaultLibCheck` を指定すると `/// <reference no-default-lib="true"/>` が指定されたファイルだけ、スキップされるようになります。


## `/// <amd-module />`
デフォルトでは AMD モジュールは匿名で生成されます。
そのため、生成されたモジュールを他のツールから使用する際に問題となります。

`amd-module` ディレクティブを使用すると、任意のモジュール名を指定することが可能になります。

以下のように指定すると AMD `define` 呼び出し時に `NamedModule` という名前が追加されます。

```ts:amdModule.ts
///<amd-module name="NamedModule"/>
export class C {
}
```
```js:amdModule.js
define("NamedModule", ["require", "exports"], function (require, exports) {
    var C = (function () {
        function C() {
        }
        return C;
    })();
    exports.C = C;
});
```

## `/// <amd-dependency />`
**注:** このディレクティブは非推奨です。代わりに `import "moduleName";` を使用してください。

`/// <amd-dependency path="x" />` ディレクティブは非 TypeScript モジュールへの依存関係を指定するために使用します。

`amd-dependency` ディレクティブは任意の `name`  プロパティを持っており、amd モジュール名を指定することができます。

```ts:TypeScript
/// <amd-dependency path="legacy/moduleA" name="moduleA"/>
declare var moduleA:MyType
moduleA.callStuff()
```
```js:JavaScript
define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) {
    moduleA.callStuff()
});
```