エラーの内容
パッケージをインポートすると、TypeScript が即座にこのエラーを投げます:
Could not find a declaration file for module 'library-name'. '/path/to/node_modules/library-name/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/library-name` if it exists or add a new declaration (.d.ts) file containing `declare module 'library-name';` ts(7016)
ビルドが失敗します。エディタが赤くなります。デプロイパイプラインがブロックされます。
なぜこのエラーが発生するのか
TypeScript がモジュールの公開内容(関数、パラメータ、戻り値の型)を把握するには、型情報が必要です。その情報は .d.ts 宣言ファイルに記述されています。
パッケージに型情報が含まれていない場合、TypeScript はそのモジュールの構造を把握できません。暗黙的な any を明示的に許可しない限り、処理を続行しません。ts(7016) が発生する主な状況は3つあります:
- パッケージが型情報をバンドルしていない純粋な JavaScript である
- コミュニティパッケージ
@types/library-nameがインストールされていない - 対応する
.d.tsファイルなしでローカルの JS ファイルをインポートしている
修正方法1:@types パッケージのインストール(最も一般的)
まず、コミュニティが DefinitelyTyped 上で型を既に作成しているか確認します:
npm install --save-dev @types/library-name
# yarn の場合
yarn add -D @types/library-name
# pnpm の場合
pnpm add -D @types/library-name
よく使うパッケージの例:
npm install --save-dev @types/lodash
npm install --save-dev @types/express
npm install --save-dev @types/node
npm install --save-dev @types/react @types/react-dom
インストール後、VS Code で TypeScript サーバーを再起動します:Ctrl+Shift+P → TypeScript: Restart TS Server。これで完了です。
パッケージの存在を事前に確認する
npm info @types/library-name
パッケージ情報が返ってきた場合はインストールします。404 のようなエラーが出た場合はコミュニティ型が存在しないため、修正方法2に進みます。
修正方法2:宣言ファイルを自分で作成する
どこにも型が存在せず、今すぐブロックを解除する必要がある場合は、プロジェクト内に宣言ファイルを作成します:
mkdir -p src/@types
src/@types/library-name.d.ts を作成します:
declare module 'library-name';
たった1行です。TypeScript に「このモジュールは存在します。すべての内容を any として扱ってください」と伝えます。根本的な解決ではなくワークアラウンドですが、すぐにブロックを解除できます。
改善策:実際に使う部分だけに型をつける
インポートするデータの形状がわかっている場合は、具体的に型を定義しましょう。すべてのエクスポートを型付けしなくても、実際の型安全性が得られます:
declare module 'legacy-analytics' {
interface TrackOptions {
event: string;
userId?: string;
properties?: Record<string, unknown>;
}
export function track(options: TrackOptions): void;
export function identify(userId: string): void;
export default { track, identify };
}
修正方法3:tsconfig.json で宣言ファイルのパスを指定する
TypeScript は .d.ts ファイルを自動的に検出しません。tsconfig.json を開いて typeRoots と include を確認します:
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./src/@types"
]
},
"include": [
"src",
"src/@types"
]
}
注意すべき落とし穴:typeRoots が定義されているが ./node_modules/@types が省略されている場合、インストールされているすべての @types パッケージが暗黙的に無視されます。このエントリが1つ欠けているだけで、多くの頭を悩ませる問題が発生します。
修正方法4:JS から TS への段階的な移行に allowJs を使う
JavaScript プロジェクトを移行中に自分の JS ファイルで ts(7016) が発生している場合は、tsconfig.json に以下を追加します:
{
"compilerOptions": {
"allowJs": true,
"checkJs": false
}
}
TypeScript は通常の JS から型を推論します。明示的な宣言は不要です。段階的な移行に適しています。
修正方法5:緊急回避策(恒久的に使い続けないこと)
締め切りが1時間後で型付けを後回しにする場合は、暗黙的な any のチェックを無効にします:
{
"compilerOptions": {
"noImplicitAny": false
}
}
または、特定のインポートのみ抑制します:
// @ts-expect-error -- TODO: untyped-library の型を追加する
import legacyLib from 'untyped-library';
// @ts-ignore の代わりに // @ts-expect-error を使用しましょう。その違いは重要です:@ts-expect-error は抑制が不要になったときに警告を出します。@ts-ignore は永遠に沈黙します。
動作確認
修正を適用したら、正しく解決されたか確認します:
# エラーゼロ = 解決済み
npx tsc --noEmit
# ts(7016) のみを確認する
npx tsc --noEmit 2>&1 | grep 7016
VS Code でインポートにカーソルを合わせたとき、any の代わりに実際の型シグネチャが表示されていれば、型が正しく読み込まれています。
予防策
- JS ライブラリを追加する前に、対応する
@typesパッケージを検索しましょう。多くが存在しており、インストールに10秒もかかりません - 最近の多くのパッケージは型情報を直接バンドルしています。
package.jsonに"types"または"typings"フィールドがないか確認しましょう。@typesパッケージが不要な場合があります - CI に
tsc --noEmitを追加する — コードレビューに到達する前に新たな問題を検出できます - カスタム宣言のために
src/@types/をバージョン管理に含める。.d.tsファイルをプロジェクト全体に散在させないようにしましょう

