TypeScriptで型定義がないライブラリを使う方法!DefinitelyTypedと自作型の作り方
生徒
「TypeScriptで便利なライブラリをインストールしたのですが、赤線が出てエラーになってしまいます。どうすればいいですか?」
先生
「それは、そのライブラリに型定義ファイルという説明書がない状態ですね。TypeScriptは型がないと、中身が何かわからなくて不安になってしまうんです。」
生徒
「どうすればTypeScriptにそのライブラリの使い方を教えてあげられますか?」
先生
「プロジェクト内で型を補う方法や、世界中の人が作ってくれた型定義を使う方法があります。詳しく解説しますね!」
1. 型定義ファイル(d.ts)とは何かを学ぼう
TypeScriptは、プログラムの中で使われるデータが数字なのか、文字なのかを厳しくチェックする言語です。このチェックのおかげで、実行する前に間違いを見つけることができます。しかし、世の中には「JavaScript」という、型を気にせずに作られたライブラリがたくさんあります。
JavaScriptで作られたライブラリをTypeScriptで読み込むと、TypeScriptは「この道具(ライブラリ)はどうやって使えばいいの?中身は何が入っているの?」とパニックになり、エラーを出してしまいます。そこで必要になるのが型定義ファイルです。拡張子が .d.ts で終わるこのファイルは、いわばライブラリの「取り扱い説明書」のような役割を果たします。この説明書があることで、TypeScriptは初めて見るライブラリでも安心して処理できるようになります。
2. 世界の有志が作るDefinitelyTyped(@types)の活用
一番簡単で推奨される方法は、DefinitelyTypedという巨大な型定義プロジェクトから説明書をダウンロードすることです。これは、世界中のプログラマーが「この有名なライブラリの型定義を作っておいたよ!」と共有してくれている場所です。
使い方は非常にシンプルで、npm install @types/ライブラリ名 というコマンドを実行するだけです。例えば、有名な lodash というライブラリを使う場合、本体とは別に型定義をインストールします。これにより、自分で難しい設定を書かなくても、すぐに型チェックや入力補完(コードを打っている途中で候補が出てくる機能)が効くようになります。プログラミング初心者のうちは、まずこの @types が存在するかを確認するのが鉄則です。
3. 開発環境でのインストールコマンドを確認しよう
実際にコマンドプロンプトやターミナルで入力する例を見てみましょう。ここでは、多くのプロジェクトで使われる設定を想定しています。--save-dev(または -D)というオプションをつけるのが一般的です。これは「この型定義は開発するときにだけ必要で、完成した製品には含めなくていいですよ」という意味になります。
// 1. ライブラリ本体をインストール
// npm install jquery
// 2. 対応する型定義ファイルをインストール
// npm install --save-dev @types/jquery
このように、本体と型定義をセットで用意することで、TypeScriptプロジェクトは正常に動作します。もし @types/ライブラリ名 を探しても見つからない場合は、次のステップである「自作」に進むことになります。
4. プロジェクト内で型を自作して補う方法
もし世界中の誰も型定義を作っていないマイナーなライブラリや、社内だけで使っている古いライブラリを使う場合は、自分で「これはこういうライブラリですよ」と宣言する必要があります。これをアンビエント宣言と呼びます。
プロジェクトのルート(一番上の階層)に types というフォルダを作り、その中に index.d.ts というファイルを作成するのが一般的です。まずは「この名前のライブラリは存在しますよ!」とだけ伝える、最もシンプルな書き方から覚えましょう。これだけで、TypeScriptはエラーを出すのをやめてくれます。一番簡単な「何でも許容する」設定は以下の通りです。
// types/manual-library.d.ts などの名前で作成します
declare module "my-unknown-library";
declare module というのは、「これからこのモジュール(ライブラリ)について説明します」という合図です。後ろにライブラリ名をダブルクォーテーションで囲って書きます。中身を空にしておくと、そのライブラリの機能は何を使っても any(何でもOK)という型として扱われます。
5. tsconfig.jsonの設定で自作ファイルを読み込む
型定義ファイルを作っただけでは、TypeScriptはそれに気づいてくれません。設定ファイルである tsconfig.json を編集して、自作の説明書を読み込むように指示を出す必要があります。パソコンの設定画面をいじるような感覚で、一箇所だけ書き換えましょう。
具体的には、typeRoots という項目を修正します。デフォルトでは node_modules/@types だけを見に行くようになっていますが、ここに自分が作ったフォルダを追加します。この設定を忘れると、いくらファイルを作っても「型が見つかりません」というエラーが消えないので注意してください。
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types"
]
}
}
これで、標準の型定義フォルダと、自分が作った types フォルダの両方を探してくれるようになります。料理をするときに、備え付けのレシピ本と、自分で書いたメモの両方を参照するようなイメージですね。
6. 具体的な関数の型を定義してみよう
ただ「存在する」と伝えるだけでなく、もう少し詳しく「この関数は文字を渡すと数字を返します」といった説明を加えると、プログラミングがぐっと楽になります。これを細かく書くほど、ミスをしたときにパソコンがすぐに教えてくれるようになります。
例えば、calculateAge という関数を持つライブラリの定義を書いてみましょう。初心者の方でも、(名前: 型) => 戻り値の型 という形を覚えるだけで、基本的な定義は書けるようになります。以下のコードは、ライブラリの具体的な中身を定義する例です。
// types/my-library.d.ts
declare module "my-calculation-tool" {
// helloという関数は、引数(名前)が文字列で、何も返さない(void)
export function hello(name: string): void;
// addという関数は、2つの数字を受け取って、数字を返す
export function add(a: number, b: number): number;
}
export というのは「外から使えるようにする」という意味です。このように定義しておけば、実際のプログラムを書くときに、数字を入れるべき場所に間違えて文字を入れてしまったら、即座にエラーが表示されます。
7. 外部からファイルを読み込む際の注意点
型定義を自作する際に初心者が陥りやすい罠が、ファイルの配置場所です。プロジェクトの構成が複雑になってくると、TypeScriptがファイルを見失うことがあります。基本的には、プロジェクトの全ファイルを監視しているフォルダの中に .d.ts ファイルを置くことが重要です。
また、ファイル名の先頭に @ をつけるような特殊なライブラリ名の場合、フォルダ構成もそれに合わせる必要があります。しかし、最初は難しいことは考えず、プロジェクトの直下に custom.d.ts というファイルを作り、そこに declare module を並べていくスタイルから始めるのがおすすめです。少しずつ慣れてきたら、ライブラリごとにファイルを分けるなど、整理整頓をしていきましょう。
8. エラーが消えない時のチェックリスト
型定義を設定したはずなのに、どうしてもエラーが消えないことがあります。そんな時は、落ち着いて以下の項目をチェックしてみてください。パソコンは嘘をつきませんが、設定の読み込みに時間がかかることがあります。
- エディタを再起動する: VSCodeなどのソフトが、古い設定を覚えたままになっていることがあります。
- ファイル名を確認する:
.d.tsになっていますか?.tsではありません。 - スペルミスを確認する: ライブラリの名前が一文字でも違うと、TypeScriptは別のものだと判断します。
- tsconfig.jsonの保存: 設定ファイルを保存しないと、変更が反映されません。
これらを確認するだけで、解決することがほとんどです。特にVSCodeを使っている場合は、Ctrl + Shift + P を押して「TypeScript: Restart TS server」を実行すると、ソフトを閉じずに型チェックをやり直してくれるので便利です。
9. 型の定義を段階的に強化するコツ
最初から完璧な型定義を作るのはプロでも大変です。まずは declare module "ライブラリ名"; だけでエラーを消し、その後に頻繁に使う関数だけ型を付けていく「段階的な定義」がおすすめです。無理をして全てを定義しようとすると、プログラムを作る前に疲れてしまいます。
プログラミング未経験の方は、まずは「型定義はエラーを黙らせるための魔法の呪文」くらいに思っておいて大丈夫です。慣れてくると、この呪文が自分をバグから守ってくれる最強の盾になることに気づくはずです。TypeScriptの厳しさは優しさだと捉えて、少しずつ型定義ファイルと仲良くなっていきましょう。