初めてのTypeScriptプログラム
インストールと設定についての学習が終わったところで、いよいよ最初のTypeScriptプログラムを書いてみましょう。コードの記述から実行まで、TypeScriptのワークフロー全体を順を追って確認していきましょう。
1. プロジェクトファイルを作成する
前回のレッスンで作成したプロジェクトディレクトリ内に、src/hello.ts という名前の新しいフォルダを作成してください:
my-project/
├── src/
│ └── hello.ts ← Create this file
├── tsconfig.json
└── package.json
hello.ts に以下のコードを入力してください:
// First TypeScript Program
let username: string = "Charlie";
let age: number = 18;
function greet(name: string, userAge: number): string {
return name + " This year " + userAge + " years old";
}
console.log(greet(username, age));
このコードとJavaScriptの最大の違いは、各変数やパラメータの後に型注釈が付く点です(: string、: number)。
2. 型アノテーションの概要
型アノテーションはTypeScriptの中核となる構文であり、その形式は非常にシンプルです:変数名 + コロン + 型。
let Variable Name: Type = value;
(1) 基本型に対する共通の注釈
let name: string = "Diana"; // String
let age: number = 20; // Numbers
let isStudent: boolean = true; // Boolean value
let score: number = 95.5; // Decimals are also number
let nothing: null = null; // null
let empty: undefined = undefined; // undefined
(2) 関数型のアノテーション
関数には、パラメータ型と戻り値型の2つを指定する必要があります。
function Function Name(Parameters: Parameter Types): Return Type {
// Function Body
}
- パラメータの種類:各パラメータの後に
: typeを追加する - 戻り値の型:パラメータを含む括弧の後に
: typeを追加してください
▶ 例:型注釈付きの関数
// Calculate the sum of two numbers
function add(a: number, b: number): number {
return a + b;
}
// Concatenating Strings
function joinWords(first: string, second: string): string {
return first + " " + second;
}
console.log(add(3, 5));
console.log(joinWords("Hello", "The World"));
出力:
8
Hello The World
void:function log(msg: string): void { console.log(msg); } と記述してください。
3. TypeScript コードのコンパイル
After writing the .ts file, you need to compile it into .js before you can run it.
(1) 単一ファイルの手動コンパイル
tsc src/hello.ts
これにより、同じディレクトリに src/hello.js という名前のファイルが作成されます。このファイルを開くと、すべての型注釈が消えていることがわかります:
// Compiled hello.js
var username = "Charlie";
var age = 18;
function greet(name, userAge) {
return name + " This year " + userAge + " years old";
}
console.log(greet(username, age));
これがTypeScriptの型消去です。型注釈はコンパイル時にのみ有効となり、生成されるJavaScriptコードは手書きのJSとほぼ同じになります。
(2) tsconfig.json を使用してプロジェクト全体をコンパイルする
プロジェクトに tsconfig.json が含まれている場合は、プロジェクトのルートディレクトリで次のコマンドを実行してください:
tsc
コンパイラは、設定ファイル内の rootDir および outDir のエントリに従って、すべての .ts ファイルをバッチコンパイルします。
▶ 例:コンパイルと実行
# Go to the project directory
cd my-project
# Compilation(According to tsconfig.json Layout)
tsc
# Run the compiled JS
node dist/hello.js
出力:
Charlie This year 18 years old
dist/hello.js であり、src/hello.ts ではありません。TypeScript の開発ワークフローは常に、.ts ファイルの作成 → コンパイル → .js ファイルの実行という順序になります。
4. 型チェックの威力を体感しよう
TypeScriptの最大の強み――コンパイル時にエラーを検出すること。あえて間違ったコードを書いてみて、TypeScriptがどのようにそれを検知するか見てみましょう。
(1) 型の不一致
let score: number = 90;
score = "Excellent"; // ❌ Error:You cannot convert the type"string"Assigned to Type"number"
このコードはJavaScriptでは「文法的には」正しく動作しますが、後で score を数学演算で使用すると問題が発生します。TypeScriptでは、コンパイル時にこの問題を即座に検出します。
(2) パラメータの型が不正です
function add(a: number, b: number): number {
return a + b;
}
add(3, "5"); // ❌ Error:Type"string"Parameters cannot be assigned to types"number"parameters
JavaScript では、add(3, "5") は "35" を返します(文字列の連結)。これは、ほぼ間違いなく期待した結果ではないでしょう。TypeScript では、間違った引数を渡したことを事前に警告してくれます。
(3) 存在しないメソッドを呼び出す
let name: string = "Charlie";
name.toFixed(2); // ❌ Error:Type"string"The property does not exist"toFixed"
toFixed は number 型のメソッドですが、string には存在しません。JavaScript では実行時に TypeError エラーが発生しますが、TypeScript ではコンパイル時にこのエラーが検出されます。
▶ 例:JavaScriptとTypeScriptにおけるエラー検出の比較
// ===== JavaScript Version:The problem wasn't discovered until runtime =====
let userAge = "25"; // String "25"
let nextYear = userAge + 1; // No errors will occur,But the result was "251" rather than 26
console.log(nextYear); // Output "251" —— That's not what we want.!
// ===== TypeScript Version:Intercepted at compile time =====
let userAge2: number = 25; // Clearly labeled as a number
let nextYear2: number = userAge2 + 1; // Correct:25 + 1 = 26
console.log(nextYear2); // Output 26
出力:
251
26
"25" + 1は26ではなく"251"として評価されます。これは初心者が陥りがちな落とし穴です。TypeScriptでは、型チェック機能により、コンパイル時にこうした問題を未然に防ぐことができます。
5. tsc --watch: 自動コンパイル
.ts ファイルを変更するたびに、手動で tsc を実行するのは面倒すぎます。--watch モード(略して -w)を使用すると、コンパイラがファイルの変更を監視し、ファイルが保存されるやいなやコンパイルを行ってくれます:
tsc --watch
または、1つのファイルを指定します:
tsc src/hello.ts --watch
有効にすると、ターミナルには次のように表示されます:
[8:30:15 PM] Starting compilation in watch mode...
[8:30:15 PM] Found 0 errors. Watching for file changes.
ファイルを保存するたびに自動的に再コンパイルされます。ユーザーはnode dist/xxx.jsの出力に集中すればよいだけです。
▶ 例:開発中のワークフロー全体
# Terminal 1:Enable Automatic Compilation
tsc --watch
# Terminal 2:Run and Test
node dist/hello.js
# Edit src/hello.ts Run it again
node dist/hello.js
ts-node をインストールすれば、.ts ファイルを直接実行することもできます(手動でのコンパイル手順を省略できます):npm install -g ts-node、続いて ts-node src/hello.ts。このツールは学習には非常に便利ですが、本番環境ではやはり通常のコンパイル手順に従う必要があります。
6. 型推論――TypeScriptがこれほど賢い理由
すべての変数に型注釈が必要ではないことに気づいた方もいるかもしれません。TypeScriptは、変数の初期値に基づいてその型を自動的に推論できるほど賢いのです:
let name = "Diana"; // TS Automatically inferred as string
let age = 20; // TS Automatically inferred as number
let isActive = true; // TS Automatically inferred as boolean
これは、次のコードと完全に同等です:
let name: string = "Diana";
let age: number = 20;
let isActive: boolean = true;
ルールは単純です。初期値が指定されている場合、TypeScriptは型を推論できるため、型注釈を省略できます。初期値が指定されていない場合は、型を明示的に指定する必要があります。
▶ 例:型アノテーションはいつ指定する必要があるか?
// ✅ Has an initial value——Type can be inferred,Comments may be omitted
let message = "Hello";
let count = 0;
// ❌ No initial value——The type must be specified.,Otherwise TS The default is any
let userId: number; // Must be labeled
let userEmail: string; // Must be labeled
// ❌ Do not label = Implicit any(strict An error occurs in this mode)
let userId2; // ❌ Error:Variables implicitly have"any"Type
strict: true モードでは、初期値や型指定がない変数を使用するとエラーになります。これは良いことです。これにより、各変数の型を明示的に指定するよう強制され、曖昧な any が至る所に現れるのを防ぐことができます。
❓ よくある質問
letではなくvarが使われているのですか?tsconfig.json内のtargetの設定によって異なります。targetをES5(非常に古いバージョン)に設定すると、互換性を確保するためにコンパイラがletとconstをvarに変換します。ES2020以上に設定すると、letとconstが保持されます。ES2020に設定することをお勧めします。node dist/xxx.js を実行するのは面倒です。もっと簡単な方法はありませんか?npm install -g ts-node) をインストールすれば、ts-node src/xxx.ts を実行するだけで、手動でのコンパイル手順を省略できます。VS Code 用の Code Runner 拡張機能も、TS ファイルのワンクリック実行に対応しています。ただし、本番環境のプロジェクトでは、依然として tsc によるコンパイルプロセスに従うことをお勧めします。📖 まとめ
- 型注釈の構文:
let variableName: type = value;関数の引数や戻り値にも注釈を付けることができます - TypeScript はコンパイル後に型消去を行うため、生成された JavaScript コードには型情報が含まれません。
- TypeScriptの中核となる価値:コンパイル時に型エラーを検出し、実行時の問題を未然に防ぐこと
tsc --watch自動的にコンパイルする、ts-nodeTSファイルを直接実行する- 型推論により、変数に初期値を手動で指定する必要はなくなりますが、初期値のない変数については、明示的に指定する必要があります。
- 厳格モードでは、暗黙的な
anyはエラーを発生させます。これは良いことです。これにより、型を明確に指定せざるを得なくなるからです。
📝 練習問題
- 基本演習(難易度 ⭐):
src/hello.tsを作成し、型指定(文字列、数値、ブール値)付きの変数を3つ定義して、プログラムをコンパイル・実行した後、console.logを使用してそれらの値を出力してください。 - 上級問題(難易度 ⭐⭐):長方形の面積を計算する型注釈付き関数
calculateArea(width: number, height: number): numberを作成してください。意図的に文字列のパラメータを渡して、TypeScript のコンパイルエラーメッセージを確認し、そのエラーを修正してください。 - 課題(難易度:⭐⭐⭐):JavaScriptとTypeScriptが同じエラーコードのセットをどのように扱うかを比較してください。3種類のエラー(文字列を数値として扱った場合、存在しないメソッドを呼び出した場合、および未定義のプロパティにアクセスした場合)を含むJavaScriptコードを記述し、それをTypeScriptで書き直して、TypeScriptが各エラーをどの行で報告するかを明記してください。



