Dev Study
← 解説「strictなTypeScript設定 — 壊れる前に知らせてくれる」に戻る

サンプルコードで身につける: strictなTypeScript設定 — 壊れる前に知らせてくれる

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1ng newが既定で有効にする設定を確認する

新規プロジェクトのtsconfig.jsonを開くと、strictとstrictTemplatesが最初から有効になっています。自分で設定する必要はなく、この既定を「切らない」ことが大切です。

// tsconfig.json(抜粋)— ng new my-app が生成した直後の状態
{
  "compilerOptions": {
    "strict": true,
    "noImplicitOverride": true,
    "noFallthroughCasesInSwitch": true
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

2null安全 — 「あるかもしれない」を型で扱う

strictの中核はstrictNullChecksです。undefinedを返すかもしれない関数の結果をそのまま使うとコンパイルエラーになります。ifで絞り込むと、そのブロック内では型がUserに確定します。

type User = { name: string };

// find は「見つからない」可能性があるので User | undefined を返す
function findUser(users: User[], name: string): User | undefined {
  return users.find((u) => u.name === name);
}

const found = findUser([], 'Tanaka');

// console.log(found.name);
// => エラー: 'found' is possibly 'undefined'
//    実行前に「null かもしれない」参照を教えてくれる

if (found) {
  console.log(found.name); // if で絞り込めば安全に使える
}

3strictTemplates — テンプレートの型チェック

strictTemplatesが有効だと、HTMLテンプレート内のバインディングも型チェックされます。存在しないプロパティ名の参照や、入力プロパティへの型違いの代入が、ビルド時とエディタ上で検出されます。

import { Component, input } from '@angular/core';

@Component({
  selector: 'app-price-tag',
  template: '<span>{{ price }}円</span>',
})
export class PriceTag {
  // number 型の入力プロパティ
  price = input.required<number>();
}

// 使う側のテンプレートでの型チェック(strictTemplates の効果):
//   <app-price-tag [price]="1200" />     → OK
//   <app-price-tag [price]="'1200'" />   → エラー: string は number に代入不可
//   <span>{{ prise }}</span>              → エラー: 'prise' は存在しない(打ち間違い)

4暗黙のanyを禁止する — noImplicitAny

strictには、型注釈のない引数を暗黙にany扱いすることを禁止するチェックも含まれます。引数に型を書くよう促されることで、関数の入出力が契約として明文化され、補完も効くようになります。

// ── Before: strict だとコンパイルエラーになる ──
// function total(items) {
//   // => Parameter 'items' implicitly has an 'any' type
//   return items.reduce((sum, item) => sum + item.price, 0);
// }

// ── After: 引数の型を書く(関数の契約が明文化される)──
type Item = { price: number };

function total(items: Item[]): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// 型を書いたことで、呼び出し側の間違いもすぐ検出される
// total(['100', '200']);  => エラー: string[] は Item[] に代入不可

5エラーは通知 — ビルドエラーの読み方

strict設定のエラーは「このままだと実行時に壊れる可能性がある」という事前通知です。エラーメッセージにはファイル名・行番号・理由が含まれるので、落ち着いて場所と理由を読み取れば対処できます。

ng build

# エラー出力の例:
# ✘ [ERROR] TS18048: 'found' is possibly 'undefined'.
#     src/app/user-list/user-list.ts:15:17

# 読み方:
#   TS18048             → エラー番号(検索の手がかりになる)
#   possibly 'undefined' → undefined の可能性を処理していない
#   user-list.ts:15:17  → 場所(15行目・17文字目)

# 対処の定石: if で絞り込む / ?? で既定値 / 型の定義を見直す
# 設定を緩めて黙らせるのは最後の手段