【実務・中級編】 string型の定義とテンプレートリテラル型 – TypeScript実践ガイド

TypeScriptの文字列型とテンプレートリテラル型:ただの「string」で終わらせないための設計哲学

こんにちは。現場でコードを書いていて、こんな経験はないだろうか?

「APIから返ってくるこの文字列、結局どのパターンがあるんだっけ?」「型定義を `string` にしちゃったけど、後から別のエンジニアが変な値を突っ込んでバグった…」

`string` 型は、TypeScriptにおいて最も基本的でありながら、最も「思考停止」を誘発する魔の型でもある。今日は、中級エンジニアの君たちが、単なる「文字の入れ物」以上の意味を型に持たせ、堅牢で美しいコードを書くための処方箋を授けよう。

—

1. string とは何か:ランタイムと静的解析の境界線

ブラウザのJavaScriptエンジン(V8など)にとって、文字列はメモリ上に確保された連続したバイナリデータだ。しかし、TypeScriptの `string` 型は、あくまで「開発者がその変数に文字列を代入することを許可する」というコンパイル時のルールに過ぎない。

ここで意識すべきは、「型が広すぎる」ことの弊害だ。

// 悪い例:なんでも受け入れてしまう
type UserInfo = {
id: string; // これだと uuid なのか email なのか、ただの適当な文字列なのか判別不能
};

実務では、`string` をそのまま使うのではなく、「その文字列がどのような形式であるべきか」を型システムに語らせる必要がある。

—

2. テンプレートリテラル型:型レベルの「文字列結合」

TypeScript 4.1で導入されたテンプレートリテラル型は、単なる文字列結合の道具ではない。「文字列のパターンを型で縛り上げる」ための最強の武器だ。

例えば、CSSの単位や、特定の命名規則を持つIDを型安全に扱いたいとき、これを使わない手はない。

// 1. 基本:定数との組み合わせ
type Size = ‘small’ | ‘medium’ | ‘large’;
type Padding = `padding-${Size}`;

const p1: Padding = ‘padding-small’; // OK
// const p2: Padding = ‘padding-extra’; // コンパイルエラー!

// 2. 実践:特定のプレフィックスを持つキーを縛る
// APIのレスポンスやイベント名などで非常に強力
type EventName = `on${Capitalize}`;

const onClick: EventName = ‘onClick’; // OK
const onHover: EventName = ‘onHover’; // OK
// const onScroll: EventName = ‘scroll’; // コンパイルエラー!

この記法を使えば、`string` という広大な海の中で、「ここにはこのパターンしか来ない」という境界線を引くことができる。

—

3. 【現場の知見】型を絞り込むための「ブランド型」と「テンプレートリテラル」

中級から上級へステップアップする君たちに教えたいのは、「文字列を型で偽装する」テクニックだ。ただの `string` にラベルを貼ることで、意味論的に安全なコードを書く。

/

  • テンプレートリテラル型を活用したURL生成器
  • 型安全にパスを構築し、ミスを未然に防ぐ

/
type ApiPath = `/api/v1/${string}`;

function fetchApi(path: ApiPath) {
console.log(`Fetching from ${path}…`);
}

// 完璧に動作する
fetchApi(‘/api/v1/users’);

// コンパイルエラー!
// パターンが違うため、エンジニアに「ここを直せ」と警告を出せる
// fetchApi(‘/api/v2/users’);

このように、テンプレートリテラル型を関数の引数に使うことで、「ドキュメントを読まなくても、型が仕様を教えてくれる」状態を作れる。これが、僕が考える「アーキテクチャの美しさ」だ。

—

4. 陥りがちな罠:`string` を極端に排除しすぎない

ただし、ここで一つ忠告がある。「なんでもかんでも型で縛ればいいというわけではない」ということだ。

例えば、ユーザーが自由に入力するテキストボックスの値を、無理やりテンプレートリテラル型で縛ろうとすると、逆にコードが複雑になりすぎてメンテナンスコストが跳ね上がる。

  • 定型的な文字列(ID、パス、ステータス、CSSの定数など): テンプレートリテラル型で徹底的に縛る。
  • 動的なユーザー入力: `string` 型を受け入れつつ、バリデーションロジック(Zodなど)で実行時に検証する。

このバランス感覚こそが、シニアエンジニアの腕の見せ所だ。

—

まとめ:次にコードを書くとき、自問してほしい

君たちが次に `string` と書くとき、一瞬だけ立ち止まってこう考えてみてほしい。

> 「この文字列には、もっと具体的な『型』の形があるのではないか?」

`string` という型を、単なる「文字の入れ物」から、「意図を伝えるためのドキュメント」へと昇華させる。その小さな積み重ねが、半年後の君たちを助ける堅牢なコードベースを作るはずだ。

型定義は、コードの「制約」ではなく、チーム全員の「共通言語」だ。ぜひ、明日のコミットから試してみてほしい。何かあれば、いつでもコードレビューするから持ってきなさい。応援しているよ。

コメント

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