型宣言は、「.d.ts」という拡張子を持つファイルです。これは、JSDoc アノテーションと同様に、型付けされていない JavaScriptコードに TypeScript の型を結びつけるための方法です。
また「JavaScript で定義されたこのようなものが存在しており、それについて私が説明します」と TypeScript に伝えるための方法です。
型宣言は、その用途にかかわらず、スクリプトモードの.tsまたは.d.tsファイルの中に存在している必要があります。
型宣言の用途
- コンパイルされた TypeScript を、誰かが TypeScript アプリケーションから使用するときに、TypeScript アプリケーションの TSC インスタンスは、生成された JavaScript ファイルに対応する .d.ts ファイルを探します。このファイルは、プロジェクトについて、どのような型が存在しているかを TypeScript に伝えます。
- TypeScript をサポートしているコードエディター(たとえば VSCode )は、これらの .d.ts ファイルを読み取って、ユーザーに対して( TypeScript を使わないとしても)、入力したときに有益な型のヒントを提示します。
- TypeScript コードの不必要な再コンパイルを避けることで、コンパイル時間を大幅に短縮します。
型宣言の構文
- 型宣言は型だけを含むことができ、値を含むことはできません。つまり、関数、クラス、オブジェクト、および変数の実装を持つことはできず、パラメーターのデフォルト値を持つこともできません。
- 型宣言は、値を定義することはできませんが、JavaScript 内のどこかで定義される値が「存在する」ことは宣言できます。このために、特別な declare キーワードを使います。
- 型宣言は、利用者から見えるものについての型だけを宣言します。エクスポートされない型や、関数の本体内のローカル変数の型のようなものは含みません。
型宣言を書き出してみる
以下のコードの型宣言を書き出してみます。
type SamT ={
num: number
str: string
}
interface SamI{
a:number
get():number
set(a:number):void
}
class Sam<T>{
bl: boolean = false
constructor(private a: T) {
this.a = a
}
get(): T {
return this.a
}
set(a: T) {
this.a = a
}
static create<T>(a: T): Sam<T> {
return new Sam<T>(a)
}
sam(): void
sam(a: T): void
sam(a?: T): void {
}
}
tsconfig.json に以下の設定を追加します。
{
"compilerOptions": {
"declaration": true,
}
}
これで index.ts をトランスパイル(ビルド)すると同じディレクトリ内に 以下のindex.d.ts ファイルが作成されます。
declare type SamT = { //③
num: number;
str: string;
};
interface SamI { //④
a: number;
get(): number;
set(a: number): void;
}
declare class Sam<T> { //①
private a;
bl: boolean;
constructor(a: T);
get(): T;
set(a: T): void;
static create<T>(a: T): Sam<T>;
sam(): void; //②
sam(a: T): void;
}
前項の「型宣言の構文」と照らし合わせ見てください。
- ①: class の前に declare がついています。これは index.js は index.d.ts で宣言されている型をエクスポートしていますよという宣誓のようなものです。
- ②: 型宣言は実装を含まないので、オーバーロードが保持されるだけで、その実装についてのシグネチャは保持されません。
- その他の箇所も実装、値は含まれず、型の宣言のみが記述されています。
- ③④: 型とインターフェースには class のように declare がついていません。
型宣言ファイル内のトップレベルの値は declare キーワードを必要としますが(declarelet、declarefunction、declareclassなど)、トップレベルの型やインターフェースは、必要ではありません。
index.d.ts は、実装のない index.ts にすぎません。言い換えれば、index.ts から型だけを抜き出したものということになります。
.ts ファイルで js コードを動かす
以下のコードは JavaScript では実行できますが、TypeScript ではコンパイルエラーになります。
x = 10;
console.log(x);
では上記コードを TypeScript でも実行できるようにするにはどうすればよいでしょうか。
その時に用いるのがアンビエント宣言( declare )です。
アンビエント宣言( declare )
型宣言について話すときには、値を含む通常の宣言と区別するために、これらをアンビエントと呼ぶことがあります。
上記のコードのように変数をアンビエント宣言する必要がある場合は、以下コードのように「declare」キーワードを使って変数を宣言します。
declare var x: number;
上記コードのようなアンビエント宣言は index.d.ts のように型定義ファイル(.d.ts)と呼ばれるファイルに記述します。.tsファイルに記述もできます。
型定義ファイルは「src/@types」というふうに ts ファイルが配置されているディレクトリに「@types」ディレクトリを作成して配置しておくのが一般的です。
ディレクトリ名は「@types」でなくとも任意名でも問題なく実行できました。
以下のようになります。
ts_test
├─ js
└─ src
├─ @types
│ └─ index.d.ts
└─ index.ts
これで JavaScript で記述されている index.ts を実行できるようになります。
Node.js の Javascriptライブラリーの使用
JavaScript のライブラリを TypeScript で利用する場合は型宣言が必要になります。
Node.js の JavaScript ライブラリでは型宣言が用意されているものもあります。(おそらく大体は用意されているかと思います)
もっとも有名な JavaScript ライブラリの一つでもある jquery も型宣言が用意されています。
Node.js の jquery を試してみる
実際に Node.js の jquery を使ってみたいと思います。
jquery をインストール
まずは jquery をインストールします。
npm install jquery
「node_modules」ディレクトリの中に「jquery」ディレクトリが追加されます。
jquery の型宣言をインストール
jquery は、JavaScript のライブラリーなのでインストールしただけでは、TypeScript(.tsファイル)では使えません。
使えるようにするために型宣言をインストールします。
npm install @types/jquery –save-dev
「node_modules」ディレクトリの中の「@types」ディレクトリ直下に「jquery」ディレクトリが追加されます。
これで TypeScript(.tsファイル)で jquery が使えるようになります。
ただ jquery は HTML の DOM 操作を簡単にするた為のライブラリですので、ブラウザで実行する必要があります。
browserify のインストール
ここの内容は型宣言とは関係ないのですが、流れ的に簡単に説明します。
Node.js の jquery をブラウザで実行する為には、browserify をインストールする必要があります。
browserify は、Node.js のツールです。
なぜ必要かというと、jquery 等のライブラリを読み込む為に使う「require」をブラウザがサポートしていないからです。
browserify を使う事によって「require」を使う事ができるようになります。
詳しく知りたい方はググってみて下さい。詳しく説明しているサイトは沢山あります。
npm install –save-dev browserify
「node_modules」ディレクトリの中に browserify に関連するディレクトリが複数追加されます。
browserify の型宣言をインストール
Typescript で使うのでもちろん型宣言もインストールします。
npm install –save @types/browserify
「node_modules」ディレクトリの中の「@types」ディレクトリ直下に「browserify」ディレクトリが追加されます。
browserifyでトランスパイルして実行
これで Typescript で jquery を使用し、ブラウザで実行する準備が整ったので、実行してみます。
以下は、実行コードです。
<!DOCTYPE html>
<html lang="ja">
<head>
<script src="./js/index.js" type="module"></script>
</head>
<body>
<h1>h1タグ</h1>
</body>
</html>
const $ = require('jQuery');
$(function () {
alert("jQueryを読み込み");
$('h1').css('color', 'red');
});
実行します。
npx browserify src/index.ts -o js/index.js
「src/index.ts」で .ts ファイルを指定しています。「-o js/index.js」でトランスパイルしたファイルを出力先を指定しています。
これで「js/index.js」ファイルが追加されます。
●実行結果

●ディレクトリ構成
任意ディレクトリ/
│
├─node_modules/
│ │
│ ├─@types/
│ │ │
│ │ ├─jquery/
│ │ │
│ │ └─browserify/
│ │
│ ├─jquery/
│ │
│ └─ browserify/(その他複数)
│
├─src/
│ └─index.ts
│
├─js/
│ └─index.js
│
├─ index.html
│
├─ package.json
│
├─ tsconfig.json
│
└─ tslint.json
webpack を使用すると「import」を使った読み込みもできるような事が書いてあった記事も目にしたので、興味のある方は調べてみて下さい。