0Pricing
TypeScript Academy · レッスン

補間の型安全性

文字列から補間変数を抽出し、必須にします。

「補間の型安全性」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

型安全な補間

メッセージには "Hello, {name}" のようなプレースホルダーが含まれることがあります。型安全な i18n では、メッセージ文字列の型からプレースホルダー名を抽出し、一致する引数を渡すよう要求します。

目標

メッセージのリテラル型から、そのメッセージが必要とする変数のオブジェクト型を計算します。これにより、t("greet", { name: "Ada" }) の形式が強制され、name の不足がコンパイルエラーになります。

1つのプレースホルダーを抽出する

テンプレートリテラル条件型を使うと、1つのプレースホルダーを含む文字列から変数名を取り出せます。実際のコードでは、パターンをバッククォートで囲み、string、開き波括弧、infer V、閉じ波括弧、string と記述します。ここではそのマッチャーを BraceMatch と表します。

// Real TS pattern (backtick template literal):
//   matches any text, then {V}, then any text; infers V.

type Var<S extends string> =
  S extends BraceMatch<infer V> ? V : never;

type A = Var<"Hello, {name}">; // "name"

複数のプレースホルダーを抽出する

再帰してすべてのプレースホルダーをユニオン型に集めます。パターンで1つの変数と残りの末尾部分を取得し、その末尾に対して再帰します。

// Pattern: any text, {V}, then Rest tail -- infer V and Rest.

type Vars<S extends string> =
  S extends BraceMatchRest<infer V, infer Rest>
    ? V | Vars<Rest>
    : never;

type B = Vars<"Hi {first} {last}!">; // "first" | "last"

名前から Args オブジェクトへ

mapped type を使って、名前のユニオン型を必須プロパティを持つオブジェクト型に変換します。

type ArgsOf<S extends string> = {
  [K in Vars<S>]: string | number;
};

type G = ArgsOf<"Hello, {name}">;
// { name: string | number }

プレースホルダーがなければ引数も不要

メッセージにプレースホルダーがない場合、Vars は never になるため、引数オブジェクトは空になります。その場合は args パラメーターを省略可能にできます。

type C = Vars<"Goodbye">;       // never
type D = ArgsOf<"Goodbye">;     // {} (empty)

型付き翻訳関数

選択されたキーからメッセージのリテラルを取得して引数を計算し、args パラメーターがそのキーに応じて変化するようにします。

declare const messages: {
  greet: "Hello, {name}";
  invite: "Join {count} others";
};

declare function t<K extends keyof typeof messages>(
  key: K,
  args: ArgsOf<(typeof messages)[K]>
): string;

実際の強制

これでコンパイラーは、各メッセージが宣言している変数を正確に渡すよう要求します。

t("greet", { name: "Ada" });   // ok
t("greet", {});                 // Error: name is missing
t("invite", { count: 3 });      // ok
t("invite", { name: "x" });     // Error: count missing, name unexpected

通常のメッセージでは args を省略可能にする

条件付きオーバーロードを使うと、プレースホルダーのないメッセージでは2番目の引数自体を不要にできます。

type MaybeArgs<S extends string> =
  Vars<S> extends never ? [] : [args: ArgsOf<S>];

declare function t2<K extends keyof typeof messages>(
  key: K,
  ...rest: MaybeArgs<(typeof messages)[K]>
): string;

カスタム区切り文字

カタログで {{name}} や %{name} を使う場合は、Vars のテンプレートリテラルパターンをそれに合わせて調整します。手法は同じで、周囲のリテラルだけが変わります。

これが重要な理由

補間変数の不足や入力ミスは、壊れた UI 文字列("Hello, undefined")を生む典型的な原因です。これらを型レベルで抽出すれば、コンパイルエラーとして検出でき、各メッセージの契約も明確に記述できます。

クイックチェック

補間の型安全性についての理解度を確認します。

まとめ

テンプレートリテラルと infer を使ってメッセージの リテラル型にパターンマッチングすると、プレースホルダー名をユニオン型として抽出し、それらを必須の args オブジェクトに対応付けられます。これにより、translate 関数は必要な変数を正確に要求し、変数がない場合は args を省略できるようになります。

よくある質問

「補間の型安全性」レッスンは無料ですか?

はい。「補間の型安全性」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「補間の型安全性」で何を学びますか?

文字列から補間変数を抽出し、必須にします。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「補間の型安全性」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 翻訳キーの型付け
  2. 補間の型安全性
  3. 型による複数形処理
  4. ロケール対応の型推論
← TypeScript Academyに戻る