ICU MessageFormat is a string syntax for translatable text: a single message encodes its own variables, plural forms, and category choices, so it renders correctly for any set of values without the caller stitching grammar together by hand. It is the format behind FormatJS, react-intl, and Android string resources, and it exists because real sentences are grammar, not concatenation — "1 item" versus "3 items" is a decision the message itself must make. You implement icuMessageFormatter(message, values), which parses one ICU string and returns the finished text.
function icuMessageFormatter(
message: string, // an ICU MessageFormat string
values: Record<string, unknown>, // a value per named argument
): string; // the formatted output
A plural argument picks a branch from a count, and each # inside the chosen branch becomes that count:
const msg = '{count, plural, =0 {no items} one {# item} other {# items}}';
icuMessageFormatter(msg, { count: 0 }); // 'no items' (exact =0 wins)
icuMessageFormatter(msg, { count: 1 }); // '1 item' (one)
icuMessageFormatter(msg, { count: 7 }); // '7 items' (other, # -> 7)
A select argument picks a branch by matching a string value, falling back to other:
const msg = '{gender, select, male {he} female {she} other {they}}';
icuMessageFormatter(msg, { gender: 'female' }); // 'she'
icuMessageFormatter(msg, { gender: 'droid' }); // 'they' (no match -> other)
{name} is replaced with values.name. A message with no {...} at all comes back unchanged.=N {..} branch first (so =0 {no items} beats the categories); otherwise apply the keyword rule, where a count of 1 selects one and every other count selects other. Replace each # in the chosen branch with the count.String(values[arg]); when none matches, use the other branch, which a well-formed select always provides.{..} inside a branch must not be mistaken for the branch's closing brace. Track brace depth instead of splitting on the first } you meet.{n, number, percent}. Assume every {...} is a simple argument, a plural, or a select.