JavaScriptの基礎はもう身につけた。
でも 次のステップ に進みたいと思っていませんか?
そんなあなたに最適なのが TypeScript — JavaScriptをそのままパワーアップさせる言語です。
💡 記事にポイント
この記事では、TypeScriptの 必要性・導入方法・基本の型や書き方 といった学習の大枠が理解できるように解説。
細かいテクニックは、#2以降で解説しますので、先ずはプロジェクト作成から実行までのポイントを掴んで下さい。
JavaScriptで感じていた不安 — 「実行時までバグが見つからない…」 — を解消し、より 堅牢で予測可能なコード を書けるようになります。
JavaScript習得の次のステップへ、プロジェクト・チーム開発・大規模アプリでも怖くない自信を手に入れましょう!
TypeScriptとは?
TypeScriptは、Microsoftが開発したJavaScriptに型システムを追加したプログラミング言語です。
JavaScriptのスーパーセット(上位互換)なので、既存のJavaScriptコードはそのままTypeScriptとして動作します。
なぜTypeScriptを使うのか?
JavaScriptの課題:バグが実行時まで分からない(公開後にバグの存在に気づくことが多くなる。)
// JavaScriptではこんなバグが実行時まで分からない
function greet(name) {
return "Hello, " + name.toUpperCase();
}
greet(123); // 実行時エラー!name.toUpperCase is not a function
TypeScriptなら:開発過程でコンパイル時に問題を発見できる。
function greet(name: string) {
return "Hello, " + name.toUpperCase();
}
greet(123); // コンパイル時にエラー!型が違うと教えてくれる
TypeScriptの3つのメリット
- バグの早期発見:コードを書いている段階でエラーに気づける
- コードの可読性向上:型情報が「このコードは何をするか」を明確にする
- 開発効率UP:エディタの補完機能が強力になる
環境構築
必要なもの
- Node.js(バージョン14以上推奨)
- テキストエディタ(Cursor, Visual Stuio Codeなど)
Node.jsやnpmコマンドの学習がまだの場合は、事前にNode.js入門に目を通してみてください。
インストール
# TypeScriptをグローバルにインストール
npm install -g typescript
# バージョン確認
tsc --version
「tsc」は、TypeScriptコンパイラの略でコンパイラコマンドとして言語実行します。
実践 プロジェクトの初期化
# プロジェクトフォルダを作成
mkdir typescript-tutorial
cd typescript-tutorial
# package.jsonを作成
npm init -y
# TypeScriptとts-nodeをインストール
npm install --save-dev typescript ts-node @types/node
# tsconfig.jsonを生成
npx tsc --init
インストールするパッケージの説明
- typescript: TypeScriptコンパイラ本体。
.tsファイルを.jsファイルに変換するために必要 - ts-node: TypeScriptファイルを直接実行できるツール。開発時に
tscでコンパイルせずにすぐ実行できて便利 - @types/node: Node.jsの型定義ファイル。
console.logやprocessなどNode.jsの機能を型安全に使うために必要
なぜ--save-devを使うのか?
--save-devオプションは、開発時のみ必要なパッケージであることを示します。
本番環境では、コンパイル後のJavaScriptファイル(.js)だけがあれば動作するため、TypeScript関連のツールは開発時のみ必要です。
TypeScriptプロジェクトの設定ファイルで、コンパイラの動作やプロジェクトの構造を定義します。
生成されたtsconfig.jsonは複雑なので、初心者向けにシンプルな設定に書き換えましょう。
tsconfig.jsonを開いて、以下の内容で上書きしてください:
//tsconfig.json
{
"compilerOptions": {
// コンパイル先のJavaScriptバージョン
"target": "ES2020",
// 使用できる機能(配列のfindメソッドなどを使うために必須)
"lib": ["ES2020"],
// モジュールシステム
"module": "commonjs",
// バンドラーを想定した解決方式 一般的なプロジェクトで推奨
"moduleResolution": "bundler",
// ソースファイルの場所
"rootDir": "./src",
// コンパイル後のファイルの出力先
"outDir": "./dist",
// 厳密な型チェックを有効化
"strict": true,
// デバッグ用のソースマップを生成
"sourceMap": true,
// その他の推奨設定
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
// コンパイル対象のファイル
"include": ["src/**/*"],
// 除外するディレクトリ
"exclude": ["node_modules", "dist"]
}ディレクトリ構造の作成
# ソースコード用のディレクトリを作成
mkdir src最終的なプロジェクト構造:
typescript-tutorial/
├── src/ ← TypeScriptファイルをここに置く
│ └── index.ts
├── dist/ ← コンパイル後のファイル(自動生成される)
├── node_modules/ ← インストールしたパッケージ
├── package.json
└── tsconfig.jsonpackage.jsonにスクリプトを追加
package.jsonを開いて、"scripts"セクションを以下のように修正:
{
"name": "typescript-tutorial",
"version": "1.0.0",
"scripts": {
"dev": "ts-node src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.0",
"typescript": "^5.3.0"
}
}これで準備完了です!
TypeScriptの基本的な型
プリミティブ型
JavaScriptの基本的なデータ型に型を付けられます。
// 文字列
let username: string = "太郎";
// 数値
let age: number = 25;
// 真偽値
let isActive: boolean = true;
// null と undefined
let empty: null = null;
let notDefined: undefined = undefined;
配列
// 数値の配列
let numbers: number[] = [1, 2, 3, 4, 5];
// 文字列の配列
let fruits: string[] = ["apple", "banana", "orange"];
// ジェネリック記法(同じ意味)
let colors: Array<string> = ["red", "blue", "green"];
ジェネリックは「TypeScript入門#3」で詳しく解説します。
現時点では、こんな書き方があると考えるだけでも良いです。
オブジェクト
// オブジェクトの型定義
let user: { name: string; age: number } = {
name: "花子",
age: 30
};
// より複雑なオブジェクト
let product: {
id: number;
name: string;
price: number;
inStock: boolean;
} = {
id: 1,
name: "ノートPC",
price: 120000,
inStock: true
};
関数
「引数」や「戻り値」に「データ型」を定義するところがJavaScirptとの違いです。
// 引数と戻り値に型を付ける
function add(a: number, b: number): number {
return a + b;
}
// アロー関数
const multiply = (a: number, b: number): number => {
return a * b;
};
// 戻り値がない場合はvoid
function logMessage(message: string): void {
console.log(message);
}
Union型(複数の型を許可)
「複数の型のうちいずれか一つ」を表現する型です。|(パイプ)演算子を使って定義します。
// 文字列または数値を受け取れる
let id: string | number;
id = "ABC123"; // OK
id = 999; // OK
// id = true; // エラー!
// 関数での使用例
function printId(id: string | number): void {
console.log("ID:", id);
}
printId("ABC"); // OK
printId(123); // OK
型エイリアス(Type Alias)
同じ型定義を再利用できます。
// 型に名前を付ける
type User = {
name: string;
age: number;
email: string;
};
let user1: User = {
name: "太郎",
age: 25,
email: "taro@example.com"
};
let user2: User = {
name: "花子",
age: 30,
email: "hanako@example.com"
};
//もし、型エイリアスがなかったら?
let user3: {
name: string;
age: number;
email: string;
} = {
name: "花子",
age: 30,
email: "hanako@example.com"
};
もし、型エイリアスがなかったらuser3のように変数を作る毎に冗長的なオブジェクトの型を書かないといけないが、型エイリアスがあると「User」型と別名を書くだけで良くなる。
インターフェース(Interface)
オブジェクトの形を定義する別の方法です。
インターフェースは「TypeScript入門 #4」で詳しく解説します。
定義した型の変数に値を代入する方法は同じですが、少し性質が変わってきます。
現時点では、インターフェースと言うものがあるぐらいに思ってください。
interface Product {
id: number;
name: string;
price: number;
description?: string; // ?を付けるとオプショナル(省略可能)
}
let laptop: Product = {
id: 1,
name: "ノートPC",
price: 120000
// descriptionは省略可能
};
let smartphone: Product = {
id: 2,
name: "スマートフォン",
price: 80000,
description: "最新モデル"
};
実践例:簡単なTodoアプリの型定義
それでは、学んだ知識を使って実際にコードを書いてみましょう。
src/index.tsを作成して、以下のコードを書いてください:
// Todoの型定義
type Todo = {
id: number;
title: string;
completed: boolean;
createdAt: Date;
};
// Todoリスト
let todos: Todo[] = [];
// Todoを追加する関数
function addTodo(title: string): void {
const newTodo: Todo = {
id: todos.length + 1,
title: title,
completed: false,
createdAt: new Date()
};
todos.push(newTodo);
}
// Todoを完了にする関数
function completeTodo(id: number): void {
const todo = todos.find(t => t.id === id);
if (todo) {
todo.completed = true;
}
}
// 使用例
addTodo("TypeScriptを学ぶ");
addTodo("記事を書く");
completeTodo(1);
console.log(todos);
TypeScriptファイルの実行
TypeScriptファイルを実行する方法は主に2つあります。
方法1:ts-nodeで直接実行(開発時に推奨)
最も簡単な方法です。コンパイルせずに直接index.tsを実行できます。
# 直接実行
npx ts-node src/index.ts
# または、package.jsonのスクリプトを使う
npm run dev
出力例:
[
{
id: 1,
title: 'TypeScriptを学ぶ',
completed: true,
createdAt: 2024-01-15T10:30:00.000Z
},
{
id: 2,
title: '記事を書く',
completed: false,
createdAt: 2024-01-15T10:30:00.000Z
}
]方法2:コンパイルしてから実行(本番環境向け)
TypeScriptをJavaScriptに変換してから実行します。
# ステップ1: コンパイル(ファイル名は指定しない!)
tsc
# または
npm run build
# ステップ2: 生成されたJavaScriptを実行
node dist/index.js
# または
npm start
コンパイルする(2行目か4行目実行)と、dist/ディレクトリに.jsファイルと.js.mapファイルが生成されます。
方法2は、生成したjsを実行させている
typescript-tutorial/
├── src/
│ └── index.ts ← 元のTypeScriptファイル
├── dist/
│ ├── index.js ← コンパイル後のJavaScript
│ └── index.js.map ← ソースマップ(デバッグ用)
└── ...⚠️ よくある間違い
# ❌ ファイル名を指定するとtsconfig.jsonが無視される
tsc src/index.ts
# ❌ これだとコンパイルエラーになる
tsc index.ts
# ✅ 正しい方法:ファイル名を指定しない
tsc重要:
tscコマンドにファイル名を指定すると、tsconfig.jsonの設定が”無視”されます。
プロジェクト全体をコンパイルするには、単にtscとだけ実行してください。
開発フローのまとめ
開発中(コードを書いて試す):
npm run dev本番用にビルド:
npm run build
npm startよく使う型のTips
型推論を活用する
TypeScriptは賢いので、明らかな場合は型を省略できます。
// 型を明示的に書く
let message: string = "Hello";
// 型推論に任せる(推奨)
let message2 = "Hello"; // 自動的にstring型と推論される
// 配列も同様
let numbers = [1, 2, 3]; // number[]と推論される
anyを避ける
// ❌ 避けるべき(TypeScriptの利点が失われる)
let data: any = "文字列";
data = 123; // なんでも代入できてしまう
// ✅ 適切な型を使う
let data: string | number = "文字列";
data = 123; // OK
@types/パッケージについて
TypeScriptで既存のJavaScriptライブラリを使う場合、型定義ファイルが必要になることがあります。
@types/パッケージとは
- Node.js自体はJavaScriptで書かれていて、TypeScriptの型情報を持っていない
- `@types/node`はNode.jsの機能(`console`, `process`, `fs`など)に型情報を追加する
- これにより、TypeScriptがNode.jsの機能を理解し、補完やエラーチェックができる
- `@types/`で始まるパッケージは、既存のJavaScriptライブラリに型定義を追加するもの
よく使う@types/パッケージ
# Node.jsの型定義
npm install --save-dev @types/node
# Reactの型定義(Reactを使う場合)
npm install --save-dev @types/react
# Expressの型定義(Expressを使う場合)
npm install --save-dev @types/express
型定義ファイルが必要かどうかの見分け方
// パッケージをインストール
// npm install lodash
import _ from 'lodash';
// エラーが出る場合は型定義が必要
// その場合、型定義をインストール
// npm install --save-dev @types/lodash
import _ from 'lodash';
// エラーが消える!最近のライブラリは、型定義を内蔵している(TypeScriptで書かれている)ことも多いため、必ずしも@types/パッケージが必要とは限りません。
まとめ
この記事では、TypeScriptの基礎を学びました。
今回学んだこと
- TypeScriptとは何か、なぜ使うのか
- 環境構築の方法
- 基本的な型:string, number, boolean, 配列, オブジェクト
- 関数の型定義
- Union型で複数の型を許可する方法
- Type AliasとInterfaceでコードを整理する方法
- 実践的なTodoアプリの例
次回以降で深掘りする内容
- ジェネリクス:より柔軟な型定義
- 高度な型操作:Mapped Types, Conditional Typesなど
- クラスとオブジェクト指向
- 型ガードとタイプナローイング
- 実践的なプロジェクト構成
まずはこの記事の内容を実際に試してみて、TypeScriptの便利さを体感してください!
次回は、これらの基礎を踏まえて、より高度な型システムの機能を学んでいきます!
TypeScript入門シリーズ
第1回: 環境構築から全体像まで
第2回: 型の基礎を深く理解する
第3回: 関数と型、ジェネリクス入門
第4回: インターフェースとクラス
第5回: 実践編 – 実際のプロジェクトでの活用


























