0Pricing
TypeScript Academy · Lesson

Interpolation Type Safety

Extract and require interpolation variables from strings.

Interpolation Type Safety is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Type-Safe Interpolation

Messages often contain placeholders like "Hello, {name}". Type-safe i18n extracts those placeholder names from the message string type and requires you to pass matching arguments.

The Goal

Given the literal type of a message, we want to compute the object of variables it needs, so t("greet", { name: "Ada" }) is enforced and a missing name is a compile error.

Extracting One Placeholder

A template literal conditional type pulls the variable name out of a single-placeholder string. In real code the pattern is written with backticks as: string, open-brace, infer V, close-brace, string. We denote that matcher as BraceMatch below.

// 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"

Extracting Multiple Placeholders

Recurse to collect every placeholder into a union. The pattern captures one variable plus the remaining tail, then recurses on the tail.

// 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"

From Names to an Args Object

Turn the union of names into a required object type with a mapped type.

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

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

No Placeholders, No Args

When a message has no placeholders, Vars is never, so the args object is empty. We can make the args parameter optional in that case.

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

A Typed Translate Function

Make the args parameter depend on the chosen key by looking up the message literal and computing its 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;

Enforcement in Action

The compiler now insists on the exact variables each message declares.

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

Optional Args for Plain Messages

Use a conditional overload so messages without placeholders do not require a second argument at all.

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;

Custom Delimiters

If your catalog uses {{name}} or %{name}, adjust the template literal pattern in Vars accordingly. The technique is the same, only the surrounding literal changes.

Why This Matters

Missing or mistyped interpolation variables are a classic source of broken UI strings ("Hello, undefined"). Extracting them at the type level turns these into compile errors and documents each message contract.

Quick Check

Test your understanding of interpolation type safety.

Recap

By pattern-matching message literal types with template literals and infer, you extract placeholder names into a union, map them to a required args object, and make the translate function demand exactly those variables, optional when there are none.

Frequently asked questions

Is the “Interpolation Type Safety” lesson free?

Yes — the full text of “Interpolation Type Safety” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Interpolation Type Safety”?

Extract and require interpolation variables from strings. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Interpolation Type Safety” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Typing Translation Keys
  2. Interpolation Type Safety
  3. Pluralization with Types
  4. Locale-Aware Type Inference
← Back to TypeScript Academy