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` という型を、単なる「文字の入れ物」から、「意図を伝えるためのドキュメント」へと昇華させる。その小さな積み重ねが、半年後の君たちを助ける堅牢なコードベースを作るはずだ。
型定義は、コードの「制約」ではなく、チーム全員の「共通言語」だ。ぜひ、明日のコミットから試してみてほしい。何かあれば、いつでもコードレビューするから持ってきなさい。応援しているよ。

コメント