1日目のゴールと全体像
1日目のテーマは 「TypeScriptで“電卓アプリ”を作るための基礎を、コードのイメージと一緒に掴むこと」 です。
この7日間で目指すのは、ブラウザ上で動くシンプルな電卓—— 「数字ボタンを押して、演算子を押して、結果が表示される」 そんな小さなアプリを、TypeScript+DOM操作で作り切ることです。
1日目では、まだ完成形は目指しません。 代わりに、次の5つを 電卓という具体的なイメージと結びつけて理解すること をゴールにします。
- 型:数字・文字列・状態を“意味のある型”として扱う
- Interface:電卓の「状態の形」を定義する
- Class:電卓そのものを「クラス」として表現する
- DOM:HTML要素をTypeScriptから触るイメージを持つ
- Event:ボタンをクリックしたときに処理が動く仕組みを理解する
型:電卓の“数字と状態にラベルをつける”
電卓で扱う値を型で表現する
電卓アプリで扱う値は、ざっくり言うと次のようなものです。
- 現在入力中の数字
- 直前までの計算結果
- 選択中の演算子(
+,-,*,/など) - 表示用の文字列
TypeScriptでは、これらを「型」で表現します。
let currentValue: number = 0; // 今入力している数字
let previousValue: number = 0; // 直前の値
let operator: string | null = null; // 現在選択中の演算子
let displayText: string = "0"; // 画面に表示する文字列
TypeScriptここで重要なのは、 「型を書くことで、何が入るべき変数なのかがはっきりする」 ということです。
number→ 数値だけが入るstring→ 文字列だけが入るstring | null→ 文字列か、まだ何も選ばれていない状態(null)
電卓は「数字」と「演算子」と「表示」が絡み合うアプリなので、 型を意識することで「どこに何が入るべきか」が自然に整理されていきます。
Interface:電卓の“状態の形”を定義する
「電卓の状態」をひとまとめにする
電卓アプリでは、 「今の状態」を一つのまとまりとして扱えると、とても分かりやすくなります。
例えば、次のような情報が「電卓の状態」です。
- 現在入力中の値
- 直前の値
- 演算子
- 表示テキスト
これをTypeScriptの interface で表現すると、こうなります。
interface CalculatorState {
currentValue: number;
previousValue: number;
operator: string | null;
displayText: string;
}
TypeScriptこの CalculatorState は、 「電卓の状態はこういう形をしている」という“約束” です。
この約束に従って、状態を一つの変数にまとめることができます。
let state: CalculatorState = {
currentValue: 0,
previousValue: 0,
operator: null,
displayText: "0",
};
TypeScriptここで深掘りしたいのは、
interfaceは「オブジェクトの形」を定義するもの- 電卓のようなアプリでは「状態の形」を決めておくと、コード全体が見通しやすくなる
ということです。
「電卓の状態は CalculatorState です」と言えるようになると、 他の人にコードを説明するときも、とても楽になります。
Class:電卓そのものを“ひとつの部品”として表現する
電卓をクラスとして設計するイメージ
TypeScriptでは、電卓そのものを class として表現できます。
「電卓クラス」は、ざっくり言うと次のような役割を持ちます。
- 状態(
CalculatorState)を持つ - 数字ボタンが押されたときの処理をする
- 演算子ボタンが押されたときの処理をする
- イコールボタンが押されたときに計算する
- 表示を更新する
これをコードのイメージにすると、こうなります。
class Calculator {
private state: CalculatorState;
constructor() {
this.state = {
currentValue: 0,
previousValue: 0,
operator: null,
displayText: "0",
};
}
inputDigit(digit: string): void {
// 数字ボタンが押されたときの処理
}
inputOperator(op: string): void {
// 演算子ボタンが押されたときの処理
}
calculate(): void {
// イコールボタンが押されたときの計算処理
}
clear(): void {
// クリアボタンの処理
}
getDisplayText(): string {
return this.state.displayText;
}
}
TypeScriptここで重要なのは、 クラスが「電卓の機能をひとまとめにした部品」になっている ということです。
- 状態は
this.stateに閉じ込める - 操作はメソッド(
inputDigit,inputOperator,calculate,clear)として表現する - 表示は
getDisplayTextで取り出す
こうすることで、 「電卓のロジック」と「画面(DOM)」を分けて考えやすくなります。
DOM:HTMLの“電卓の見た目”をTypeScriptから触る
電卓の画面をHTML+DOMでイメージする
ブラウザ上の電卓は、HTMLでこんなふうに書けます。
<div id="calculator">
<div id="display">0</div>
<div class="buttons">
<button class="digit">1</button>
<button class="digit">2</button>
<button class="digit">3</button>
<button class="operator">+</button>
<button class="operator">-</button>
<button id="equals">=</button>
<button id="clear">C</button>
</div>
</div>
TypeScriptからこのHTMLを触るには、 DOM(Document Object Model) を使います。
例えば、表示部分を取得するコードはこうです。
const displayElement = document.getElementById("display");
TypeScript数字ボタンをまとめて取得するには、こう書けます。
const digitButtons = document.querySelectorAll<HTMLButtonElement>(".digit");
TypeScriptここで深掘りしたいのは、
document.getElementByIdやdocument.querySelectorAllで「画面上の要素」を取得する- TypeScriptでは、
querySelectorAll<HTMLButtonElement>のように「要素の型」を書ける
ということです。
DOM操作は、 「電卓クラスの結果を画面に反映するための橋渡し」 になります。
Event:ボタンが押されたときに“電卓クラスを動かす”
クリックイベントで電卓を動かす
電卓アプリの一番大事な部分が、 「ボタンをクリックしたときに処理が動く」 という仕組みです。
TypeScriptでは、イベントリスナーを使ってこれを表現します。
まず、電卓クラスのインスタンスを作ります。
const calculator = new Calculator();
TypeScript次に、数字ボタンにイベントを登録します。
digitButtons.forEach((button) => {
button.addEventListener("click", () => {
const digit = button.textContent ?? "0";
calculator.inputDigit(digit);
const displayElement = document.getElementById("display");
if (displayElement) {
displayElement.textContent = calculator.getDisplayText();
}
});
});
TypeScript演算子ボタンも同様です。
const operatorButtons = document.querySelectorAll<HTMLButtonElement>(".operator");
operatorButtons.forEach((button) => {
button.addEventListener("click", () => {
const op = button.textContent ?? "+";
calculator.inputOperator(op);
const displayElement = document.getElementById("display");
if (displayElement) {
displayElement.textContent = calculator.getDisplayText();
}
});
});
TypeScriptイコールボタンとクリアボタンもイベントで動かします。
const equalsButton = document.getElementById("equals");
const clearButton = document.getElementById("clear");
equalsButton?.addEventListener("click", () => {
calculator.calculate();
const displayElement = document.getElementById("display");
if (displayElement) {
displayElement.textContent = calculator.getDisplayText();
}
});
clearButton?.addEventListener("click", () => {
calculator.clear();
const displayElement = document.getElementById("display");
if (displayElement) {
displayElement.textContent = calculator.getDisplayText();
}
});
TypeScriptここで深掘りしたいのは、
- イベントは「ユーザーの操作」と「電卓クラスのメソッド」をつなぐ役割を持っている
- クリックされるたびに「電卓の状態が変わり」「表示が更新される」という流れになっている
ということです。
イベントは、 「画面とロジックを結びつける接点」 です。
1日目で本当に掴んでほしいこと
1日目は、まだ完成した電卓を作る日ではありません。 代わりに、次の5つを 電卓という具体的なイメージと結びつけて理解する日 です。
- 型:数字・文字列・演算子・状態に「何が入るべきか」をはっきりさせる。
- Interface:電卓の状態(
CalculatorState)を「形」として定義する。 - Class:電卓そのものを
Calculatorクラスとして表現し、状態と操作をひとまとめにする。 - DOM:HTMLの電卓画面を、
document.getElementByIdやquerySelectorAllで触るイメージを持つ。 - Event:ボタンのクリックイベントで、電卓クラスのメソッドを呼び、表示を更新する流れを理解する。
この1日目のイメージがあると、 2日目以降で「実際に電卓のロジックを書いていく」ときに、 「何をどこに書けばいいか」 が迷いにくくなります。
電卓という小さなアプリの中に、 TypeScriptの基礎——型・interface・class・DOM・イベント——がぎゅっと詰まっています。 ここから少しずつ、実際のコードを肉付けしていきましょう。


