Last active
October 1, 2020 10:22
-
-
Save armanozak/f01839d47348421224eb9a8b649d6f84 to your computer and use it in GitHub Desktop.
[Variadic Tuples & Recursive Conditional Types] How tagged template literals can return type-safe functions #typescript #tip
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
type Repeat<T, Count, Acc extends any[] = []> = Acc['length'] extends Count ? Acc : Repeat<T, Count, [...Acc, T]>; | |
function i18n<Keys extends number[]>([result, ...parts]: TemplateStringsArray, ...keys: Keys) { | |
return (...param: Repeat<string, Keys['length']>) => | |
keys.reduce((acc, key, i) => acc + (param as number[])[key] + parts[i], result); | |
} | |
const introduceEn = i18n`Hi. My name is ${0}. I work as a ${1} at ${2}.`; | |
const introduceTr = i18n`Merhaba. Benim adım ${0}. ${2} şirketinde ${1} olarak çalışıyorum.`; | |
// (param_0: string, param_1: string, param_2: string) => string | |
const textEn = introduceEn('Levent Arman Özak', 'software developer', 'Volosoft'); | |
const textTr = introduceTr('Levent Arman Özak', 'yazılım geliştirici', 'Volosoft'); | |
console.log(textEn); | |
// Hi. My name is Levent Arman Özak. I work as a software developer at Volosoft. | |
console.log(textTr); | |
// Merhaba. Benim adım Levent Arman Özak. Volosoft şirketinde yazılım geliştirici olarak çalışıyorum. |
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
/* This was available before v4, but that is not the point. */ | |
function i18n<Keys extends string[]>([result, ...parts]: TemplateStringsArray, ...keys: Keys) { | |
return (params: { [K in Keys[number]]: string }) => | |
keys.reduce((acc, key: keyof typeof params, i) => acc + params[key] + parts[i], result); | |
} | |
const introduceEn = i18n`Hi. My name is ${'name'}. I work as a ${'occupation'} at ${'company'}.`; | |
const introduceTr = i18n`Merhaba. Benim adım ${'name'}. ${'company'} şirketinde ${'occupation'} olarak çalışıyorum.`; | |
// (params: {name: string, job: string, company: string}) => string | |
const textEn = introduceEn({ | |
name: 'Levent Arman Özak', | |
occupation: 'developer', | |
company: 'Volosoft' | |
}); | |
const textTr = introduceTr({ | |
name: 'Levent Arman Özak', | |
occupation: 'yazılım geliştirici', | |
company: 'Volosoft' | |
}); | |
console.log(textEn); | |
// Hi. My name is Levent Arman Özak. I work as a software developer at Volosoft. | |
console.log(textTr); | |
// Merhaba. Benim adım Levent Arman Özak. Volosoft şirketinde yazılım geliştirici olarak çalışıyorum. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment