TypeScript Academy · Lesson

Locale-Aware Type Inference

Ensure all locales share the same key structure.

Lesson 4 of 413 steps

Locale-Aware Type Inference is a free TypeScript Academy lesson on CoddyKit. This is lesson 4 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, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 4 lessons in total.

Locale-Aware Type Inference

An app ships multiple locales (en, tr, de...). We want a type that errors when any locale is missing keys present in the base, so translations never silently fall out of sync.

A Base Locale

Pick one locale (usually en) as the canonical key structure. Every other locale must match its shape.

const en = {
  greeting: "Hello",
  cart: { empty: "Empty", checkout: "Checkout" },
} as const;

type Base = typeof en;

Constraining Other Locales

Type each additional locale as the base shape. A missing key is now a compile error in that locale file.

const tr: Base = {
  greeting: "Merhaba",
  cart: { empty: "Bo\u015f", checkout: "\u00d6deme" },
};
// Omitting cart.checkout -> Error: property missing

Catching Extra Keys Too

Using the base type as the annotation also flags unknown keys that exist in a locale but not the base, catching leftover or misspelled entries.

const de: Base = {
  greeting: "Hallo",
  cart: { empty: "Leer", checkout: "Kasse" },
  extra: "oops", // Error: not in Base
};

A Helper to Define Locales

A generic helper enforces the shape while preserving each value, giving a clean per-locale definition site.

function defineLocale<T extends Base>(loc: T): T {
  return loc;
}

const fr = defineLocale({
  greeting: "Bonjour",
  cart: { empty: "Vide", checkout: "Paiement" },
});

A Registry of All Locales

Collect locales in a record. Constraining each value to Base guarantees uniform structure across the whole app.

const locales: Record<string, Base> = { en, tr, de: fr };
// every entry must have the full Base key structure

Type-Level Equality (Deep)

For stricter guarantees you can build a SameKeys type that compares key structures deeply and resolves to an error type when they differ, beyond what a plain annotation catches.

type SameKeys<A, B> =
  keyof A extends keyof B
    ? keyof B extends keyof A ? true : false
    : false;

Deriving Keys Once

Because all locales share Base, the key-path type (from the earlier lesson) is computed once from Base and reused for every locale, so t typing is locale-independent.

type Key = LeafPaths<Base>;
// same valid keys regardless of active locale

Runtime Locale Selection

At runtime you index the registry by the active locale; the type system already guaranteed each locale has the same keys, so lookups are safe.

function translate(locale: keyof typeof locales, key: Key): string {
  return getPath(locales[locale], key);
}

Detecting Missing Keys Across Locales

If you cannot annotate every file directly (e.g. JSON imports), a build-time type check compares each imported locale against Base and surfaces a diff type listing missing keys.

type Missing<L> = Exclude<keyof Base, keyof L>;
type TrMissing = Missing<typeof tr>; // never if complete

Why This Matters

Untyped i18n drifts: a key added to en is forgotten in de, shipping a blank or English string. Constraining every locale to a shared base turns that omission into a compile error, keeping all locales complete and consistent.

Quick Check

Confirm your understanding of locale-aware inference.

Recap

You chose a base locale as the canonical shape and constrained every other locale to it, so missing or extra keys fail to compile. A defineLocale helper and a constrained registry keep all locales structurally identical, and key paths are derived once from the base.

Free to start

Learn TypeScript with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
101
Lessons
352

Frequently Asked Questions

Is the “Locale-Aware Type Inference” lesson free?

Yes — the full text of “Locale-Aware Type Inference” is free to read here on the web. 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. The TypeScript Academy course includes 4 lessons in total.

What will I learn in “Locale-Aware Type Inference”?

Ensure all locales share the same key structure. 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, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Locale-Aware Type Inference” 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