SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

JavaScriptの限界を超える!TypeScript初めの一歩

【TypeScriptの基礎を学ぶ】既存JavaScriptを着実にTypeScriptへ移行する実践ガイド

JavaScriptの限界を超える!TypeScript初めの一歩 第4回

tsconfig.jsonを作り、拡張子を変える

 まずはtsconfig.jsonを作ります。プロジェクトのルートで、npx tsc --initコマンドを実行します。そして、作成されたtsconfig.jsonのコメント部分を全て削除します。

tsconfig.json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

 そして、次のように書き換えます。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,

    "rootDir": "./src",
    "outDir": "./dist",
    "moduleResolution": "node",
  }
}

 targetES2024moduleESNextに変えています。

 また、rootDiroutDirmoduleResolution(モジュール解決法)の設定を加えています。

 プロジェクトのルートのpackage.jsonの一部も書き換えます。mainsrc/index.jsdist/index.jsに変更します。

  "main": "dist/index.js",

 また、distフォルダーを作り、src/index.jssrc/index.tsに、src/sub.jssrc/sub.tsに拡張子を変更します。ファイル構成は次のようになります。

▶ファイル構成

  • プロジェクトのルート/
    • dist/ ← 作成
    • my_modules/
      • hoge/
        • index.js
        • package.json
    • node_modules/
    • src/
      • index.ts ← 拡張子変更
      • sub.ts ← 拡張子変更
    • package.json
    • tsconfig.json ← 作成、修正

 ここでプロジェクトのTypeScriptのファイルをコンパイルしてみましょう。ルートでnpx tscを実行します。するとsrc/index.tsで2つのエラー、src/sub.tsで1つのエラーが出ます。

(省略)
Found 3 errors in 2 files.

Errors  Files
     2  src/index.ts:2
     1  src/sub.ts:1

 tsconfig.jsonを次のように追記します。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,

    "rootDir": "./src",
    "outDir": "./dist",
    "moduleResolution": "node",

    "allowJs": true,
    "checkJs": false,
    "noImplicitAny": false,
  },
  "include": ["src"]
}

 この状態でnpx tscを実行するとエラーは出なくなります。

 追加した設定の意味を説明しておきます。

 allowJstrueにすると、JavaScriptファイルがインポート可能になります。何もないデフォルトの状態では .ts、.tsx、.d.ts を読み込みます。allowJstrueなら、 .js と .jsx も 読み込むようになります。

 "checkJs": falseの設定は順を追って説明します。checkJstrueに設定すると、allowJsで許可されたJavaScriptファイルに対しても型チェックを行い、エラーを報告します。checkJsのデフォルト値はfalseのため、今回は意図しないチェックを防ぐ目的で、falseを指定しています。

 noImplicitAnyfalseにすると、型注釈が存在しないケースでは、any型にフォールバックするようになります。これにより、エラーが見逃される可能性がありますが、現時点ではこれでよしとしておきます。

 "include": ["src"]で、コンパイル時に読むファイルをsrcフォルダー内のみに限定します。限定しなければmy_modulesも読み込んでしまい、エラーが発生してしまいます。

 さて、この設定でコンパイルはできるようになりましたが、実際には何もチェックをおこなっていません。これから、TypeScriptに対応していき、最終的にはallowJscheckJsnoImplicitAnyを取り除きます。

src/sub.ts、src/index.tsの更新

 それでは型付けをおこなっていきましょう。まずはsrc/sub.tsを書き換えます。

src/sub.ts
export function getInfo(fromName: string): string {
    let res: string = `from ${fromName}: This is "Sub!".`;
    return res;
}

 関数の引数、戻り値、変数にそれぞれ型を付けました。関数の引数以外は、型推論でも大丈夫ですが、ここでは変化が分かりやすいように全てに型を付けています。

 続いて、src/index.tsを書き換えます。

src/index.ts
import * as sub from "./sub.js";
import * as hoge from "hoge";

function getInfo(fromName: string): string {
    let res: string = `from ${fromName}: This is "Index!".`;
    return res;
}

console.log(getInfo("root"));
console.log(sub.getInfo("root"));
console.log(hoge.getInfo("root"));

 ここまでの変更で、tsconfig.jsonの設定を少し減らせます。checkJsnoImplicitAnyを取り除きます。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,

    "rootDir": "./src",
    "outDir": "./dist",
    "moduleResolution": "node",

    "allowJs": true,
  },
  "include": ["src"]
}

 この状態でnpx tscを実行するとエラーは出ません。しかし、"allowJs": trueを取り除くとエラーが出ます。node_modulesにインストールしたmy_modules/hoge内のファイルがJavaScriptのままだからです。

自作モジュールに型定義ファイル(.d.ts)を作成する

 次は、既存の自作モジュールに型定義ファイル(.d.ts)を作りましょう。型定義ファイルは、主にパッケージを配布するためのものです。

 パッケージの処理自体はJavaScriptでおこなわれますが、TypeScriptのプログラムから参照するためには型の情報が必要です。そこで、JavaScriptのプログラムに対応した「型の情報のファイル」を作ります。これが型定義ファイルです。

 それでは型定義ファイルを作りましょう。my_modules/hoge/index.jsと同じ階層にindex.d.tsを作成します。

▶ファイル構成

  • プロジェクトのルート/
    • (省略)
    • my_modules/
      • hoge/
        • index.js
        • index.d.ts ← 作成
        • package.json
    • (省略)

 そしてindex.jsに対応した型定義を書きます。

index.js
export function getInfo(fromName) {
    let res = `from ${fromName}: This is "Hoge!".`;
    return res;
}
index.d.ts
export function getInfo(fromName: string): string

 そして、my_modules/hoge/package.json"types": "index.d.ts"の設定を追加します。

my_modules/hoge/package.json
{
  "name": "hoge",
  "version": "1.0.0",
  "main": "index.js",
  "types": "index.d.ts",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

 "types": "index.d.ts"の設定がなくても、index.jsと同じ階層にあるindex.d.tsを探してくれます。しかしここでは、明示的に型定義ファイルを書いておきましょう。

 ここまでできたら、tsconfig.jsonから"allowJs": trueを削除します。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,

    "rootDir": "./src",
    "outDir": "./dist",
    "moduleResolution": "node",
  },
  "include": ["src"]
}

 この状態で、npx tscを実行すると、エラーが出ずにJavaScriptファイルを出力することができます。

.tsファイルから型定義ファイルを自動生成する

 既にTypeScriptで書いたファイルがある場合には、型定義ファイルを出力するのは簡単です。npx tscを実行する際に-dオプションを付けて、npx tsc -dとして実行するだけです。

 実際に実行してdistに出力したファイルを示します。

dist/index.d.ts
export {};
dist/sub.d.ts
export declare function getInfo(fromName: string): string;

 ここで出てきたdeclareについて説明します。アンビエント宣言と呼ばれるものです。

 アンビエントとは「周囲の」といった意味です。declare(アンビエント宣言)は、「実装が存在すると仮定して、型だけ定義したい」といったときに用います。型情報のみを定義する際に用います。

 ここではgetInfoを実装したsub.jsは存在しています。そのためdeclareがなくても構いません。

 ただ、のちほど説明しますが、TypeScriptの型定義だけを配布する用途もあります。そのときに、sub.jsなしで、sub.d.tsだけ配布することがあります。そうしたときにはdeclareが必要になります。そのため出力されたファイルにはdeclareが付いています。

次のページ
第2章 TypeScriptへの移植の始め方とポイント

この記事は参考になりましたか?

JavaScriptの限界を超える!TypeScript初めの一歩連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/21598 2025/09/22 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー