TypeScript 宣言ファイル
宣言ファイル(.d.ts)は、TypeScriptとJavaScriptの世界をつなぐ架け橋としての役割を果たします。これらは、型情報が欠けているJavaScriptコードに対して型定義を提供し、TypeScriptプロジェクトであらゆるJavaScriptライブラリを安全に利用できるようにします。
1. 宣言ファイルとは何か?
(1) 問題点:JSライブラリに型情報が不足している
TYPESCRIPT
// Usage lodash —— A pure JavaScript library
import _ from "lodash";
// ❌ TypeScript Error: Module not found "lodash" Statement Document
let result = _.chunk([1, 2, 3, 4], 2);
(2) 解決策:宣言ファイルには型情報が記載されている
宣言ファイルの拡張子は .d.ts であり、型宣言のみが含まれています。実装コードは含まれていません:
TYPESCRIPT
// lodash.d.ts —— Statement(Describe only the type,No implementation provided)
declare module "lodash" {
export function chunk<T>(array: T[], size: number): T[][];
export function debounce(func: Function, wait: number): Function;
// ... Additional Statements
}
宣言ファイルがあれば、TypeScriptはlodashのAPIを理解し、型チェックやコードのヒントを提供することができます。
(3) 宣言文書の3つの出典
| 出典 | 説明 | 例 |
|---|---|---|
| 組み込み宣言 | TypeScriptに含まれるもの(DOM、ES2020など) | lib.dom.d.ts |
| パッケージに含まれるもの | ライブラリの作成者は、.d.ts |
axios/index.d.ts |
| DefinitelyTyped | コミュニティが管理するサードパーティの宣言 | @types/lodash |
2. @types パッケージのインストールと使用方法
(1) 型宣言を参照する
BASH
# Check if a package has @types Statement
npm info @types/lodash
# Installation Type Declaration
npm install @types/lodash --save-dev
(2) 設置後の様子
TYPESCRIPT
// After installing @types/lodash — full type support
import _ from "lodash";
let chunks: number[][] = _.chunk([1, 2, 3, 4], 2); // ✅ Type Safety
let debounced = _.debounce(() => {}, 300); // ✅ Auto-Complete
(3) 一般的な @types パッケージ
| パッケージ名 | 対応するライブラリ |
|---|---|
@types/node |
Node.js |
@types/lodash |
Lodash |
@types/express |
エクスプレス |
@types/jest |
それは |
@types/react |
React |
@types/jquery |
jQuery |
(4) 型宣言の自動検出
TypeScript は、型宣言を次の順序で検索します:
- パッケージ内の
index.d.ts(組み込み型) node_modules/@types/に基づく声明tsconfig.json、typeRoots、およびtypesで指定された場所
3. 独自の宣言ファイルを作成する
(1) グローバル変数の宣言
script タグを使用して JavaScript ライブラリをインポートする際は、グローバル変数を宣言する必要があります:
TYPESCRIPT
// globals.d.ts
declare var jQuery: (selector: string) => HTMLElement;
declare var $: typeof jQuery;
// Usage
let el = $(".container"); // ✅ Type Safety
(2) グローバル関数の宣言
TYPESCRIPT
// globals.d.ts
declare function ga(command: string, ...args: any[]): void;
declare function gtag(type: string, eventName: string, params?: Record<string, any>): void;
// Usage
ga("send", "pageview"); // ✅
gtag("event", "click", { value: 1 }); // ✅
(3) モジュールの宣言
型指定のない npm パッケージを使用する場合は、モジュールを次のように宣言してください:
TYPESCRIPT
// declarations.d.ts
declare module "untyped-lib" {
export function doSomething(value: string): number;
export const version: string;
export default class Client {
constructor(options: { host: string; port: number });
connect(): Promise<void>;
}
}
// Usage
import Client, { doSomething, version } from "untyped-lib";
(4) モジュールの拡張—既存のモジュールへの型の追加
TYPESCRIPT
// Extensions express Module
declare module "express" {
interface Request {
user?: {
id: number;
name: string;
};
}
}
// It is now available at express.Request Safety Guidelines user Properties
import { Request } from "express";
function handler(req: Request) {
if (req.user) {
console.log(req.user.name); // ✅ Type Safety
}
}
▶ 例:カスタム JavaScript ツールの宣言の記述
TYPESCRIPT
// Suppose there is a legacy-utils.js The file has no type
// legacy-utils.d.ts —— Write a statement for it
declare module "legacy-utils" {
/**
* Format the date according to the specified pattern
* @param date - Date object or timestamp
* @param pattern - Format patterns, e.g. "YYYY-MM-DD"
*/
export function formatDate(date: Date | number, pattern: string): string;
/**
* Deep-copy objects
*/
export function deepClone<T>(obj: T): T;
/**
* Image Stabilization Function
*/
export function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number
): (...args: Parameters<T>) => void;
/**
* Default Export:Toolset Object
*/
const utils: {
formatDate: typeof formatDate;
deepClone: typeof deepClone;
debounce: typeof debounce;
};
export default utils;
}
// Usage——Full Type Support
import utils from "legacy-utils";
let dateStr = utils.formatDate(new Date(), "YYYY-MM-DD");
let cloned = utils.deepClone({ name: "Charlie" });
let debounced = utils.debounce((x: number) => console.log(x), 300);
4. 宣言ファイルの作成ルール
(1) 基本ルール
.d.tsこのファイルには宣言のみが含まれており、実装は一切含まれていません。declareキーワードを使用して外部エンティティを宣言しますexportは必須ではありません。ただし、モジュール宣言内に含まれている場合は例外です。- 最上位
exportファイルをグローバル宣言ではなくモジュール宣言にする
(2) 宣言のスコープの3つの種類
TYPESCRIPT
// ── Global Declarations(None import/export) ──
// All declarations in the file are automatically visible throughout the entire project.
declare var GLOBAL_CONFIG: { api: string };
declare function globalHelper(): void;
// ── Module Declaration ──
declare module "my-lib" {
export function helper(): void;
}
// ── File Module Declaration ──
// At the top of the document, there is import/export → The entire file is a module
import { User } from "./types";
export declare function processUser(user: User): void;
(3) タイプエクスポートに関するガイドライン
TYPESCRIPT
// ✅ Recommendations——Export Interfaces and Types
export interface User {
id: number;
name: string;
}
export type UserId = number;
// ✅ Recommendations——Exported Function Signatures
export declare function getUser(id: number): User;
// ❌ Not recommended——Export the specific implementation(.d.ts Should not be implemented)
// export function getUser(id: number): User { return ...; }
5. tsconfig での型設定
(1) typeRoots—型宣言のディレクトリを指定します
JSON
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./src/types"
]
}
}
(2) タイプ—含めるタイプパッケージを指定します
JSON
{
"compilerOptions": {
"types": ["node", "jest", "lodash"]
// Includes only these three @types packages, ignoring the rest
}
}
(3) 3つの厳格度オプション
JSON
{
"compilerOptions": {
"noImplicitAny": true, // Implicit is prohibited any
"strict": true, // Enable all strict checks
"skipLibCheck": true // Skip .d.ts File Type Validation(Speed up compilation)
}
}
❓ よくある質問
Q 宣言ファイルを作成する必要があるのはどのような場合ですか?
A 以下の3つのケースがあります:(1) 使用しているJavaScriptライブラリに@typesパッケージがない場合;(2)
scriptタグを介してインポートされたグローバル変数; (3) 既存のモジュールにカスタムプロパティを追加する必要がある場合。ほとんどの場合、@typesをインストールするだけで十分であり、独自の宣言ファイルを作成することは比較的稀な慣行です。Q
declare module と declare global の違いは何ですか?A
declare module "xxx" は外部モジュールの型を宣言するもので、npm パッケージの型情報を提供するために使用されます。declare global は、モジュールファイル内のグローバルネームスペースに宣言を追加します。これは、グローバル型(Window など)を拡張するために使用されます。これら2つのスコープは異なります。module はモジュールレベルであるのに対し、global はグローバルレベルです。Q @types パッケージとライブラリに組み込まれている型、どちらが優先されますか?
A ライブラリに組み込まれている型が優先されます。axios や zod などの最新のライブラリには、すでに
index.d.ts がパッケージ内に含まれているため、@types を別途インストールする必要はありません。@types が必要になるのは、ライブラリに独自の型が含まれていない場合のみです。両方が存在する場合、TypeScript はパッケージに含まれる宣言を優先します。Q skipLibCheck を有効にするべきですか?
A 有効にすることをお勧めします。skipLibCheck を有効にすると、すべての
.d.ts ファイルの型チェックがスキップされるため、コンパイル速度が大幅に向上します(特に大規模なプロジェクトの場合)。欠点として、サードパーティの型宣言に含まれるエラーが見逃される可能性があります。ただし、@types パッケージはコミュニティによってレビューされているため、このリスクはごくわずかです。パフォーマンス上のメリットは、リスクをはるかに上回ります。📖 まとめ
- 宣言ファイル
.d.tsは、JavaScript コードの型情報を提供します。このファイルには宣言のみが含まれており、実装は含まれていません。 - 型宣言の3つのソース:TypeScriptの組み込み、ライブラリによる提供、および@typesコミュニティパッケージ
npm install @types/package-nameを使用してサードパーティ製の型宣言をインストールする- 独自の宣言ファイルを作成する状況:型指定のない JavaScript ライブラリ、グローバル変数、およびモジュール拡張
declareキーワードを使用して外部エンティティを宣言します;declare moduleモジュール型を宣言しますtsconfig内のtypeRoots/types/noImplicitAny/skipLibCheck設定は、型の解決と厳密性を制御します
📝 練習問題
- 基本問題(難易度 ⭐):
math-helpers、add(a, b)、subtract(a, b)、および定数PIを含む、架空の JavaScript ライブラリmath-helpersの宣言ファイルを作成してください。 - 上級問題(難易度 ⭐⭐):
Stringインターフェースを拡張し、reverse(): stringメソッドを追加する宣言ファイルを作成してください。考えてみてください:なぜ、組み込み型の拡張は.d.tsファイルに記述する必要があるのでしょうか? - 課題(難易度:⭐⭐⭐):型指定のないレガシー JavaScript SDK 用の完全な宣言ファイルを作成してください。これには、名前空間
SDK、クラスSDK.Client(コンストラクタ+メソッド)、列挙型SDK.EventType、およびグローバル関数SDK.init(options)を含める必要があります。



