TypeScriptでnpmパッケージの型定義を追加する方法!@typesの基本を解説
生徒
「TypeScriptで便利なライブラリをインストールしたのですが、エラーが出て使えません。どうすればいいですか?」
先生
「それは、そのライブラリに型定義が含まれていないからかもしれませんね。TypeScriptには、外部のプログラムがどのような仕組みで動くかを教えるための型定義ファイルというものが必要です。」
生徒
「型定義ファイルですか?難しそうですね。どうやって追加すればいいんでしょうか?」
先生
「実は、コマンド一つで簡単に追加できる仕組みがあるんですよ。DefinitelyTypedというプロジェクトが提供している型定義を使ってみましょう。」
1. TypeScriptで型定義が必要な理由とは?
TypeScriptは、プログラムの中で使われるデータの種類を厳しくチェックする言語です。これを型チェックと呼びます。しかし、世の中にある多くの便利な道具、つまりnpmパッケージの中には、古いJavaScriptという言語で作られたものもたくさんあります。
JavaScriptで作られた道具には、どのデータが数字なのか、どのデータが文字なのかという説明書がついていません。そのため、そのままTypeScriptで使おうとすると、TypeScriptは「この道具の使い方がわからないよ」と怒ってエラーを出してしまいます。そこで必要になるのが、その道具の専用説明書である型定義ファイルなのです。
2. npmパッケージと型定義の関係
最近の新しいパッケージであれば、最初からTypeScriptに対応していて、インストールしただけで説明書がついていることも多いです。これを内包型と言ったりします。しかし、昔からある有名なパッケージなどは、本体とは別に説明書をダウンロードしてくる必要があります。
その説明書を一括で管理してくれているのが、DefinitelyTypedという巨大な倉庫です。この倉庫にある説明書は、すべて@types/という名前から始まる特別な名前が付けられています。私たちがコマンドを入力してインストールするのは、この倉庫にある説明書なのです。
3. @typesを使った型定義のインストール方法
では、実際にどうやってインストールするのかを見ていきましょう。パソコンの黒い画面、いわゆるターミナルやコマンドプロンプトで以下のコマンドを入力します。ここでは例として、有名な日付操作ライブラリであるlodashという道具の説明書を入れてみます。
// lodashという道具を使いたいとき、まずは本体を入れます
// npm install lodash
// 次に、その説明書である型定義ファイルを入れます
// npm install -D @types/lodash
ここで重要なのが、-Dという記号です。これは開発用という意味です。この説明書はプログラムを動かすときには必要なく、人間がコードを書いている最中にTypeScriptがチェックするためだけに使うものなので、本番用のプログラムには含めないようにするためにこの記号をつけます。
4. 型定義が当たっているか確認する方法
説明書を正しくインストールできたら、プログラムを書いてみましょう。もし説明書が入っていないと、名前の下に赤い波線が出てエラーになります。説明書が入ると、その波線が消えて、さらに入力補完という機能が働くようになります。
入力補完とは、文字を少し打つだけで「次はこの機能を使いますか?」と候補を出してくれる機能です。プログラミング未経験の方でも、この機能があればスペルミスを減らすことができ、とても楽にコードを書くことができます。
import _ from 'lodash';
// 型定義が入っていると、_. を打った瞬間に使える機能がずらっと出てきます
const result = _.capitalize('hello typescript');
console.log(result);
実行結果は以下のようになります。
Hello typescript
5. 型定義エラーを解決するステップ
もしライブラリを入れてエラーが出た場合は、まず落ち着いて以下の手順を試してみてください。これがTypeScript開発におけるトラブル解決の基本です。
まず第一に、そのパッケージに型定義が内包されているかを確認します。node_modulesというフォルダの中を見て、パッケージ名のフォルダの中に.d.tsという拡張子のファイルがあれば、それは最初から説明書が入っている証拠です。その場合は、別途@types/を入れる必要はありません。
第二に、説明書がない場合は、先ほどのコマンドを使って@types/パッケージ名を探してインストールします。もしそれでも見つからない場合は、世界中の誰もまだその説明書を書いていないということになります。その場合は、自分で型を定義するか、一時的にチェックを無視する設定が必要になりますが、初心者のうちは有名なパッケージを使うようにすれば、ほとんどの場合@types/で見つかるはずです。
6. 実際のプロジェクトでの使用例(validator)
次は、文字がメールアドレスの形式かどうかをチェックするvalidatorというパッケージを例にしてみましょう。これも型定義が必要な代表的な例です。初心者の方がよく使う機能なので、練習にぴったりです。
import validator from 'validator';
// メールアドレスの形式が正しいかチェックする道具を使います
const email = "test@example.com";
const isValid = validator.isEmail(email);
if (isValid) {
console.log("これは正しいメールアドレスですね!");
} else {
console.log("メールアドレスの形が変ですよ?");
}
このコードを書く前に、必ずnpm install validatorとnpm install -D @types/validatorを実行しておく必要があります。もし説明書を入れ忘れると、isEmailという機能がどんな種類のデータを返してくるのかTypeScriptが判断できず、警告を出してしまいます。
7. package.jsonでインストール状況を確認する
自分が今、どんな説明書をインストールしたのかは、プロジェクトの中にあるpackage.jsonというファイルを見るとわかります。このファイルは、いわば持ち物リストのようなものです。
ファイルを開いて、devDependenciesという項目を探してみてください。そこに@types/で始まる名前が並んでいれば、無事にインストールが完了しています。パソコンを触り始めたばかりの方は、ファイルの中身を見るのが少し怖いかもしれませんが、設定が書いてあるだけのテキストファイルなので安心してください。
{
"dependencies": {
"validator": "^13.11.0"
},
"devDependencies": {
"@types/validator": "^13.11.0",
"typescript": "^5.0.0"
}
}
このように、本体と説明書がペアになって管理されているのが理想的な状態です。バージョン番号が少し違っていても、基本的には問題なく動作します。
8. エラーが出たときの魔法の言葉
どうしても型定義が見つからなくてエラーが消えないけれど、どうしてもそのパッケージを使いたいという時の最後の手段があります。それはany型というものを使うか、@ts-ignoreという呪文をコメントとして書くことです。
これは「TypeScriptくん、ここは型をチェックしなくていいよ」と指示を出すものです。ただし、これを使いすぎるとTypeScriptを使っている意味がなくなってしまうので、あくまで「どうしても」という時の非常手段として覚えておいてください。基本は、しっかり説明書を探して入れることが上達への近道です。
// 説明書がないパッケージを無理やり使う例
// @ts-ignore
import oldLibrary from 'old-library';
// どんなデータでも受け入れる any 型(あまり推奨されません)
const data: any = oldLibrary.getData();
console.log(data);
9. 型定義ファイルを自分で管理する必要はない
初心者の方がよく勘違いしてしまうのが、「説明書の中身を自分で書き換えなければいけないのか?」ということです。答えはノーです。@types/でインストールしたファイルは、読み込み専用として扱います。中身はプロのエンジニアたちが正確に書き上げてくれたものなので、私たちはそれを利用させてもらうだけで良いのです。
もしパッケージの使い方が変わって説明書が古くなったら、またコマンドを打って最新版に更新すれば大丈夫です。このように、インターネットを通じて世界中の知恵を借りることができるのが、プログラミングの素晴らしいところですね。まずは恐れずに、色々なパッケージと説明書を組み合わせて、自分だけのアプリを作ってみましょう。