TypeScript | 1 日 60 分 × 7 日アプリ学習:TypeScript基礎・DOM操作 電卓編

Web APP TypeScript
スポンサーリンク
スポンサーリンク

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.getElementByIddocument.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.getElementByIdquerySelectorAll で触るイメージを持つ。
  • Event:ボタンのクリックイベントで、電卓クラスのメソッドを呼び、表示を更新する流れを理解する。

この1日目のイメージがあると、 2日目以降で「実際に電卓のロジックを書いていく」ときに、 「何をどこに書けばいいか」 が迷いにくくなります。

電卓という小さなアプリの中に、 TypeScriptの基礎——型・interface・class・DOM・イベント——がぎゅっと詰まっています。 ここから少しずつ、実際のコードを肉付けしていきましょう。

タイトルとURLをコピーしました