tsconfig.jsonを作り、拡張子を変える
まずはtsconfig.jsonを作ります。プロジェクトのルートで、npx tsc --initコマンドを実行します。そして、作成されたtsconfig.jsonのコメント部分を全て削除します。
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
そして、次のように書き換えます。
{
"compilerOptions": {
"target": "ES2024",
"module": "ESNext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"rootDir": "./src",
"outDir": "./dist",
"moduleResolution": "node",
}
}
targetをES2024、moduleをESNextに変えています。
また、rootDir、outDir、moduleResolution(モジュール解決法)の設定を加えています。
プロジェクトのルートのpackage.jsonの一部も書き換えます。mainのsrc/index.jsをdist/index.jsに変更します。
"main": "dist/index.js",
また、distフォルダーを作り、src/index.jsをsrc/index.tsに、src/sub.jsをsrc/sub.tsに拡張子を変更します。ファイル構成は次のようになります。
▶ファイル構成
-
プロジェクトのルート/
- dist/ ← 作成
-
my_modules/
-
hoge/
- index.js
- package.json
-
hoge/
- 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を次のように追記します。
{
"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を実行するとエラーは出なくなります。
追加した設定の意味を説明しておきます。
allowJsをtrueにすると、JavaScriptファイルがインポート可能になります。何もないデフォルトの状態では .ts、.tsx、.d.ts を読み込みます。allowJsがtrueなら、 .js と .jsx も 読み込むようになります。
"checkJs": falseの設定は順を追って説明します。checkJsをtrueに設定すると、allowJsで許可されたJavaScriptファイルに対しても型チェックを行い、エラーを報告します。checkJsのデフォルト値はfalseのため、今回は意図しないチェックを防ぐ目的で、falseを指定しています。
noImplicitAnyをfalseにすると、型注釈が存在しないケースでは、any型にフォールバックするようになります。これにより、エラーが見逃される可能性がありますが、現時点ではこれでよしとしておきます。
"include": ["src"]で、コンパイル時に読むファイルをsrcフォルダー内のみに限定します。限定しなければmy_modulesも読み込んでしまい、エラーが発生してしまいます。
さて、この設定でコンパイルはできるようになりましたが、実際には何もチェックをおこなっていません。これから、TypeScriptに対応していき、最終的にはallowJs、checkJs、noImplicitAnyを取り除きます。
src/sub.ts、src/index.tsの更新
それでは型付けをおこなっていきましょう。まずはsrc/sub.tsを書き換えます。
export function getInfo(fromName: string): string {
let res: string = `from ${fromName}: This is "Sub!".`;
return res;
}
関数の引数、戻り値、変数にそれぞれ型を付けました。関数の引数以外は、型推論でも大丈夫ですが、ここでは変化が分かりやすいように全てに型を付けています。
続いて、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の設定を少し減らせます。checkJs、noImplicitAnyを取り除きます。
{
"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
-
hoge/
- (省略)
そしてindex.jsに対応した型定義を書きます。
export function getInfo(fromName) {
let res = `from ${fromName}: This is "Hoge!".`;
return res;
}
export function getInfo(fromName: string): string
そして、my_modules/hoge/package.jsonに"types": "index.d.ts"の設定を追加します。
{
"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を削除します。
{
"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に出力したファイルを示します。
export {};
export declare function getInfo(fromName: string): string;
ここで出てきたdeclareについて説明します。アンビエント宣言と呼ばれるものです。
アンビエントとは「周囲の」といった意味です。declare(アンビエント宣言)は、「実装が存在すると仮定して、型だけ定義したい」といったときに用います。型情報のみを定義する際に用います。
ここではgetInfoを実装したsub.jsは存在しています。そのためdeclareがなくても構いません。
ただ、のちほど説明しますが、TypeScriptの型定義だけを配布する用途もあります。そのときに、sub.jsなしで、sub.d.tsだけ配布することがあります。そうしたときにはdeclareが必要になります。そのため出力されたファイルにはdeclareが付いています。
