今回やること
1つのTypeScriptファイルに型を付け、JavaScriptへコンパイルして実行します。
string、number、boolean- 数値の配列
- オブジェクトの型
- 関数の引数と戻り値
string | numberというunion型typeofによるnarrowing
TypeScriptは、JavaScriptへ型チェックを追加した言語です。型は実行前の確認に使われ、コンパイル後のJavaScriptからは取り除かれます。
前提条件
- JavaScriptの変数、配列、オブジェクト、関数が分かる
- Node.jsとnpmが使える
node --version
npm --version
プロジェクトを準備する
mkdir typescript-first-file
cd typescript-first-file
npm init -y
npm install --save-dev typescript
mkdir src
package.jsonへESM設定とスクリプトを追加します。devDependenciesはnpm installが作った内容を残してください。
{
"type": "module",
"scripts": {
"check": "tsc --noEmit",
"build": "tsc",
"start": "node dist/index.js"
}
}
ルートにtsconfig.jsonを作ります。
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"moduleDetection": "force",
"rootDir": "src",
"outDir": "dist"
},
"include": ["src"]
}
strictは厳しい型チェックを有効にします。rootDirは入力、outDirはコンパイル結果の保存先です。
1つのTypeScriptファイルを書く
src/index.tsを作ります。
export {};
const courseName: string = "TypeScript入門";
const lessonCount: number = 6;
const isOpen: boolean = true;
const scores: number[] = [80, 95, 75];
type Course = {
name: string;
lessons: number;
open: boolean;
scores: number[];
};
const course: Course = {
name: courseName,
lessons: lessonCount,
open: isOpen,
scores,
};
function average(values: number[]): number {
const total = values.reduce((sum, value) => sum + value, 0);
return total / values.length;
}
function formatCourseId(id: string | number): string {
if (typeof id === "number") {
return `COURSE-${id.toString().padStart(3, "0")}`;
}
return id.toUpperCase();
}
const summary = `${formatCourseId(7)}: ${course.name}`;
console.log(summary);
console.log(`レッスン数: ${course.lessons}`);
console.log(`平均点: ${average(course.scores)}`);
console.log(`公開中: ${course.open}`);
primitive、配列、オブジェクト
string、number、booleanは基本的な値の型です。number[]は「要素が数値の配列」を表します。
Courseはオブジェクトが持つpropertyと、それぞれの型を定義しています。たとえばlessonsへ文字列を入れると、実行前に型エラーになります。
関数の型
function average(values: number[]): number {
const total = values.reduce((sum, value) => sum + value, 0);
return total / values.length;
}
values: number[]は引数の型、最後の: numberは戻り値の型です。関数へ文字列の配列を渡したり、文字列をreturnしたりすると型エラーになります。
union型とnarrowing
string | numberは「文字列または数値」を表すunion型です。
function formatCourseId(id: string | number): string {
if (typeof id === "number") {
return `COURSE-${id.toString().padStart(3, "0")}`;
}
return id.toUpperCase();
}
typeof id === "number"の分岐内では、TypeScriptはidを数値へ絞り込みます。これをnarrowingと呼びます。分岐の後では数値の可能性がなくなるため、文字列のtoUpperCase()を呼べます。
global declarationの衝突を避ける
先頭のexport {}は、このファイルをmoduleとして扱う印です。moduleでは、ファイル内の変数がglobalへ追加されません。
moduleDetection: "force"も、対象ファイルをmoduleとして扱う設定です。練習ファイルを増やした時に、別ファイルの同名変数やブラウザ側のglobal declarationと衝突しにくくなります。
成功を確認する
最初に型だけを確認します。
npm run check
何もエラーが表示されず終了すれば成功です。次にJavaScriptへコンパイルし、実行します。
npm run build
npm start
次のように表示されます。
COURSE-007: TypeScript入門
レッスン数: 6
平均点: 83.33333333333333
公開中: true
dist/index.jsを開くと、型注釈やtype Courseが消えていることも確認できます。
型エラーを読む
src/index.tsのlessonCountを一時的に次のように変えます。
const lessonCount: number = "6";
型チェックを実行します。
npm run check
次の形式のエラーが表示されます。行番号は編集状況によって異なります。
src/index.ts(...): error TS2322:
Type 'string' is not assignable to type 'number'.
エラーは次の順に読みます。
src/index.ts(...): 問題のファイルと位置TS2322: エラーを調べる時に使える番号Type 'string': 実際に代入した型type 'number': 代入先が求める型
"6"を数値の6へ戻し、npm run checkが再び成功することを確認してください。
よくあるエラー
tsc: command not found
プロジェクト直下でnpm installを実行し、globalのtscではなくnpm scriptを使います。
npm install
npm run check
Cannot find nameと表示される
変数名のスペルと大文字・小文字を確認します。TypeScriptではcourseNameとcoursenameは別の名前です。
Cannot redeclare block-scoped variableと表示される
ファイル先頭のexport {}と、tsconfig.jsonのmoduleDetection: "force"を確認します。複数の練習ファイルをglobal scriptとして扱うと、同名変数が衝突することがあります。
練習
Courseへcategory: "frontend" | "backend"を追加し、courseには"frontend"を設定してください。その後"design"へ変えた時に型エラーとなることを確認します。
次のステップ
基本の型をすぐ調べたい時は、TypeScriptチートシートを使ってください。型がJavaScriptへ変換される流れは、トランスパイルとコンパイルの違いで説明しています。
参考リソース
- TypeScript for the New Programmer
- Everyday Types
- Narrowing
- tsconfig: strict
- tsconfig: moduleDetection
(最終確認: 2026年7月25日)
← 一覧に戻る