Skip to content

Instantly share code, notes, and snippets.

@NikolaRusakov
Last active February 16, 2026 12:27
Show Gist options
  • Select an option

  • Save NikolaRusakov/6b78d9d16ac170696af3ba24bbb65ad0 to your computer and use it in GitHub Desktop.

Select an option

Save NikolaRusakov/6b78d9d16ac170696af3ba24bbb65ad0 to your computer and use it in GitHub Desktop.
Simple i18n TS Template Literal Type safety
const i18nData = {
app: {
title: 'My Application',
description: 'A {type} example',
},
nav: {
home: 'Home',
profile: {
settings: 'Settings',
logout: 'Log Out',
},
},
MESSAGES: {
welcome: 'Welcome, {name}!',
items: {
one: 'You have one new message.',
other: 'You have {count} new messages.',
},
},
MESSAGE: [
{
welcome: 'Welcome, {name}!',
items: {
one: 'You have one new message.',
other: 'You have {count} new messages.',
},
},
],
} as const;
type I18nData = typeof i18nData;
// Extract all possible dot-notation paths
type Paths<T, Prefix extends string = ''> = T extends object
? {
[K in keyof T]: K extends string
? T[K] extends object
? Paths<T[K], `${Prefix}${K}_`> | `${Prefix}${K}`
: `${Prefix}${K}`
: never;
}[keyof T]
: never;
type I18nPaths = Paths<I18nData>;
const zero = 0;
const path = `MESSAGE_${zero}` satisfies I18nPaths;
const one = 1;
const path = `MESSAGE_${one}` satisfies I18nPaths; // Wrong key
@Pipe({ name: 'translateKeys', standalone: true })
export class TranslateKeysPipe implements PipeTransform {
transform(value: I18nPaths): string {
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment