import { get, isObject } from 'lodash'; import * as parser from 'string-interpolation-parser' import { CountryCode } from '../countries' export type Languages = { [countryCode in CountryCode]: Record } type Join = K extends string | number ? P extends string | number ? `${K}${"" extends P ? "" : "."}${P}` : never : never; type Leaves = [D] extends [never] ? never : T extends object ? { [K in keyof T]-?: Join> }[keyof T] : ""; export type TranslateKey = Leaves export type TranslationKeys = TranslateKey> = { [key in keyof T[CountryCode]]: U } export type TranslateParam = Record export class TranslateHelper< T extends Languages = any, U extends TranslateKey = TranslateKey, V extends TranslationKeys = TranslationKeys > { translateKey: V get keys(): V { return this.translateKey } constructor(private readonly languages: T) { this.translateKey = Object.values(this.languages).reduce( (keys, language) => ({ ...keys, ...Object.keys(language).reduce((translations, key) => ({ ...translations, [key]: key as U }), {}), }), {}, ) as V } get>( countryCode: CountryCode, key: U, { alt, params }: { alt?: CountryCode; params?: TranslateParam } = {}, ): T { const lang = this.languages[countryCode] || this.languages[alt] const text = get(lang, key, null) if(!params) return text if (isObject(text)) return parser(text, params) return parser({text}, params)['text'] } }