Pluralization with Types
Model plural forms in a type-safe way.
Pluralization with Types is a free TypeScript Academy lesson on CoddyKit — lesson 3 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 Pluralization
Languages need plural forms: "1 item" vs "2 items". Type-safe i18n models plural categories (like one / other) and requires a count argument so you never forget it.
Plural Categories
The Intl plural rules define categories such as zero, one, two, few, many, other. English uses just one and other; other locales use more.
type PluralCategory = "zero" | "one" | "two" | "few" | "many" | "other";A Plural Message Shape
Represent a pluralized message as an object keyed by category. other is the required fallback.
type PluralMessage = {
other: string;
} & Partial<Record<Exclude<PluralCategory, "other">, string>>;
const items: PluralMessage = {
one: "{count} item",
other: "{count} items",
};Distinguishing Plural vs Plain
A catalog mixes plain strings and plural objects. The arg requirements differ, so we detect the shape at the type level.
type IsPlural<M> = M extends { other: string } ? true : false;Requiring count
When a message is plural, the translate args must include a numeric count. We compute the args type conditionally.
type PluralArgs<M> = IsPlural<M> extends true
? { count: number }
: {};
type A = PluralArgs<typeof items>; // { count: number }A Typed t for Plurals
Combine the catalog lookup with the conditional args so plural messages demand count and plain ones do not.
declare const cat: {
items: { one: string; other: string };
hello: string;
};
declare function t<K extends keyof typeof cat>(
key: K,
args: PluralArgs<(typeof cat)[K]>
): string;
t("items", { count: 3 }); // ok
t("items", {}); // Error: count required
t("hello", {}); // okSelecting the Form at Runtime
At runtime, Intl.PluralRules picks the category from the count, and you read the matching string (falling back to other).
function plural(msg: { other: string; [k: string]: string }, count: number, locale: string) {
const cat = new Intl.PluralRules(locale).select(count);
return (msg[cat] ?? msg.other);
}Combining With Interpolation
Plural strings usually also contain {count}. The args type can intersect plural requirements with extracted interpolation variables from the chosen form.
type FullArgs<M> = PluralArgs<M> & ExtractVars<M>;
// count plus any {placeholders} in the messageLocales With Richer Forms
Some locales (e.g. Polish, Russian) use few and many. Because PluralCategory already includes them, a catalog can supply those keys and the same machinery handles them.
const ruItems = {
one: "{count} товар",
few: "{count} товара",
many: "{count} товаров",
other: "{count} товара",
};Enforcing the other Fallback
Because other is mandatory in PluralMessage, the type system guarantees a fallback exists, preventing a runtime case where no plural form matches.
Why This Matters
Plural bugs ("1 items") and forgotten counts are common in untyped i18n. Modeling categories as types and requiring count makes correct pluralization the default and a missing count a compile error.
Quick Check
Check your grasp of type-safe pluralization.
Recap
You modeled plurals as objects keyed by plural categories with a mandatory other fallback, detected plural messages at the type level, and required a numeric count argument via conditional types. Intl.PluralRules selects the form at runtime, and the same machinery scales to richer locales.
Frequently asked questions
Is the “Pluralization with Types” lesson free?
Yes — the full text of “Pluralization with Types” 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 “Pluralization with Types”?
Model plural forms in a type-safe way. 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 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Pluralization with Types” 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
- Typing Translation Keys
- Interpolation Type Safety
- Pluralization with Types
- Locale-Aware Type Inference