Created
April 12, 2023 18:30
-
-
Save edwinm/ac791ee4e52934fcb2d9c0ef4a14d362 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// by Simon Sturmer | |
// TypeScript Wizardry: Recursive Template Literals | |
// https://www.youtube.com/watch?v=B7ygRIQcQPE | |
// Creative Commons-licence | |
const locales = { | |
en_us: { | |
hello:'Hi {user}', | |
greetings: { | |
morning:'Good morning {user}', | |
evening:'Good evening {user}' | |
} | |
} | |
} | |
type LocaleMap = typeof locales; | |
type LocaleName = keyof LocaleMap; | |
type Locale = LocaleMap[LocaleName]; | |
let currentLocale: LocaleName = 'en_us'; | |
type PathInto<T extends Record<string, any>> = keyof { | |
[K in keyof T as (T[K] extends string | |
? K | |
: (T[K] extends Record<string, any> | |
? `${K & string}.${PathInto<T[K]> & string}` | |
: never))]: any | |
}; | |
function get(object: Record<string, unknown>, path: Array<string>, index = 0): string { | |
const key = path[index]; | |
if (key === undefined) { | |
return ''; | |
} | |
const result = object[key]; | |
if (result === undefined) { | |
return ''; | |
} | |
if (typeof result === 'string') { | |
return result; | |
} | |
return get(Object(result), path, index + 1); | |
} | |
export function t(key: PathInto<Locale>): string { | |
return get(locales[currentLocale], key.split('.')) | |
} | |
const translation = t('greetings.evening') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment