404 Not Found

404 Not Found


nginx

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 は、型宣言を次の順序で検索します:

  1. パッケージ内の index.d.ts(組み込み型)
  2. node_modules/@types/に基づく声明
  3. tsconfig.jsontypeRoots、および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) 基本ルール

(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 moduledeclare 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 パッケージはコミュニティによってレビューされているため、このリスクはごくわずかです。パフォーマンス上のメリットは、リスクをはるかに上回ります。

📖 まとめ

📝 練習問題

  1. 基本問題(難易度 ⭐)math-helpersadd(a, b)subtract(a, b)、および定数 PI を含む、架空の JavaScript ライブラリ math-helpers の宣言ファイルを作成してください。
  2. 上級問題(難易度 ⭐⭐)String インターフェースを拡張し、reverse(): string メソッドを追加する宣言ファイルを作成してください。考えてみてください:なぜ、組み込み型の拡張は .d.ts ファイルに記述する必要があるのでしょうか?
  3. 課題(難易度:⭐⭐⭐):型指定のないレガシー JavaScript SDK 用の完全な宣言ファイルを作成してください。これには、名前空間 SDK、クラス SDK.Client(コンストラクタ+メソッド)、列挙型 SDK.EventType、およびグローバル関数 SDK.init(options) を含める必要があります。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%