1テンプレートリテラル型で文字列を埋め込む
テンプレートリテラル型は、バッククォートと ${...} を使って型の中に文字列を組み立てる仕組みです。`hello_${Lang}` のように書くと、Lang の候補それぞれに hello_ を付けたリテラル型のユニオンになります。実行時のテンプレートリテラルとそっくりな書き方で、型の世界の文字列を作れます。
// バッククォートと ${...} で型の中に文字列を埋め込む
type Lang = "en" | "ja";
type Greeting = `hello_${Lang}`; // "hello_en" | "hello_ja"
const greetEn: Greeting = "hello_en";
const greetJa: Greeting = "hello_ja";
console.log(greetEn, greetJa);
// const bad: Greeting = "hello_fr"; // 候補にないのでエラー
2ジェネリクスと組み合わせてイベント名を作る
テンプレートリテラル型は組み込みの文字列操作型(Capitalize など)と組み合わせると強力です。`on${Capitalize<T>}` と書けば、"click" から "onClick" のようなイベントハンドラ名の型を機械的に導出できます。命名規則を型で保証したい場面で実務でも使われます。
// "click" → "onClick" のようなハンドラ名の型を作る
type Handler<T extends string> = `on${Capitalize<T>}`;
const onClick: Handler<"click"> = "onClick";
const onHover: Handler<"hover"> = "onHover";
console.log(onClick, onHover);
// const bad: Handler<"click"> = "click"; // on が付かないのでエラー
3Capitalize / Uncapitalize で先頭だけ変える
Capitalize は先頭1文字だけを大文字に、Uncapitalize は先頭1文字だけを小文字にします。プロパティ名(userName)とコンポーネント名(UserName)のように、先頭の大小だけが違う命名規則の対応を型で表せます。全部大文字にする Uppercase との違いを見比べましょう。
type FieldName = "userName" | "email";
// 先頭だけ大文字: "UserName" | "Email"
type LabelName = Capitalize<FieldName>;
const fieldLabel: LabelName = "UserName";
console.log(fieldLabel);
// Uncapitalize は逆方向: "UserName" | "Email" → "userName" | "email"
type BackToField = Uncapitalize<LabelName>;
const fieldKey: BackToField = "email";
console.log(fieldKey);
// Uppercase だと全部大文字になる: "USERNAME" | "EMAIL"
const constantName: Uppercase<FieldName> = "USERNAME";
console.log(constantName);
4型レベルの変換と実行時の変換を対応させる
型の Lowercase は実行時の toLowerCase と対になる存在です。表記ゆれのあるコマンド入力を小文字に正規化する関数で、戻り値の型を Lowercase<RawCommand> にしておけば「正規化済みの値である」ことが型で伝わります。toLowerCase の戻り値はただの string なので、リテラル型に戻すために型アサーションを使います。
// 入力されうる表記と、正規化後の表記を型で対応させる
type RawCommand = "Start" | "Stop" | "Pause";
type NormalizedCommand = Lowercase<RawCommand>; // "start" | "stop" | "pause"
function normalizeCommand(command: RawCommand): NormalizedCommand {
// toLowerCase の戻り値は string なので、アサーションでリテラル型に戻す
return command.toLowerCase() as NormalizedCommand;
}
const startCommand: NormalizedCommand = normalizeCommand("Start");
console.log(startCommand);
console.log(normalizeCommand("Pause"));
5実務: 設定の型から環境変数名の対応表を導出する
アプリ設定の型から、環境変数名(全部大文字)をキーにした対応表の型をマップ型と Uppercase で導出する実務例です。AppConfig にキーを足すと EnvTable の必須キーも自動で増え、環境変数の用意し忘れをコンパイラが検出します。これがないと "PORT" | "HOST" のような大文字のキー一覧を手書きして、設定の型と二重管理することになります。
type AppConfig = {
port: number;
host: string;
debug: boolean;
};
// キー名を大文字化した "PORT" | "HOST" | "DEBUG" を導出する
type EnvName = Uppercase<keyof AppConfig>;
// 環境変数は文字列で渡ってくるので、値はすべて string の対応表にする
type EnvTable = { [K in EnvName]: string };
// AppConfig にキーを足すと、ここに必須キーが増えて用意し忘れを検出できる
const envTable: EnvTable = {
PORT: "3000",
HOST: "localhost",
DEBUG: "true",
};
console.log(envTable.PORT);
console.log(envTable.HOST);