Skip to content

Commit

Permalink
Work around limitations of Typescript with an extra tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardLindhout committed Jul 3, 2020
1 parent b9192aa commit 7e0e4f3
Showing 1 changed file with 81 additions and 70 deletions.
151 changes: 81 additions & 70 deletions example/src/translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,84 +23,94 @@ type TranslationsObject<TGroup, TValue> = {


type SubscriberFunc = (n:number) => any;
type val<T> = (...params: any[]) => T
type val1<T> = T
type TranslationInput<TValue> = {
[group: string]: {
[key: string]: val<TValue> | val1<TValue>
},
}

export function createTranslations<TValue, TGroup>(t: TGroup, po: Options<TValue>): TranslationsObject<TGroup, TValue> {
// subscribers with callbacks for external updates
let sb: SubscriberFunc[] = [];

let o = po
// empty map for easier translations
let et:any = {}

// convert
// {
// homeScreen:{
// loginButton:{
// nl: 'Inloggen,
// en: 'Sign in',
// }
// }
// }
//
// to =>> based on the current language
//
// homeScreen:{
// loginButton:'Sign in',
// }
// }

function gen() {
// loop translations groups
Object.keys(t).forEach(g => {
// easierTranslation map with the group in the key
et[g] = {}

// loop translations inside group
// @ts-ignore
Object.keys(t[g]).forEach(k => {
// e.g. 'Sign in'
export function createTranslations<TValue extends object>(){
return function <TGroup extends TranslationInput<TValue>>(t: TGroup, po: Options<TValue>): TranslationsObject<TGroup, TValue> {
// subscribers with callbacks for external updates
let sb: SubscriberFunc[] = [];

let o = po
// empty map for easier translations
let et: any = {}

// convert
// {
// homeScreen:{
// loginButton:{
// nl: 'Inloggen,
// en: 'Sign in',
// }
// }
// }
//
// to =>> based on the current language
//
// homeScreen:{
// loginButton:'Sign in',
// }
// }

function gen() {
// loop translations groups
Object.keys(t).forEach(g => {
// easierTranslation map with the group in the key
et[g] = {}

// loop translations inside group
// @ts-ignore
let tv = t[g][k]

// map them in easier translation map
et[g][k] = tv instanceof Function ? (...p: any) => {
let z = (tv as Function)(...p)
return z[o.language] || z[o.fallback]
} : tv[o.language] || tv[o.fallback]
Object.keys(t[g]).forEach(k => {
// e.g. 'Sign in'
// @ts-ignore
let tv = t[g][k]

// map them in easier translation map
et[g][k] = tv instanceof Function ? (...p: any) => {
let z = (tv as Function)(...p)
return z[o.language] || z[o.fallback]
} : tv[o.language] || tv[o.fallback]
})
})
})
}
}

function setOptions(op: Options<TValue>) {
o = op
gen()
function setOptions(op: Options<TValue>) {
o = op
gen()

// call subscribers
sb.forEach((c: any) => c((p:number) => p + 1));
}
// call subscribers
sb.forEach((c: any) => c((p: number) => p + 1));
}

// use hook
function use(): any {
let [, s] = R.useState<number>(0);

// use hook
function use(): any {
let [, s] = R.useState<number>(0);
// subscribe to changes
R.useEffect(() => {
sb.push(s);
return () => {
sb = sb.filter((f) => f !== s);
};
}, [s]);

// subscribe to changes
R.useEffect(() => {
sb.push(s);
return () => {
sb = sb.filter((f) => f !== s);
};
}, [s]);
// return easier translations object
return et;
}

// return easier translations object
return et;
gen()
return {
translations: et,
getOptions: () => o,
setOptions,
use,
};
}
gen()
return {
translations: et,
getOptions: () => o,
setOptions,
use,
};
}

// first describe which languages are allowed/required (Typescript)
Expand All @@ -122,7 +132,8 @@ function getBestLanguage(): typeof availableLanguages[number] | typeof fallback


// create a translation object with your translations
const translate = createTranslations<TranslationLanguages>({

const translate = createTranslations<TranslationLanguages>()({
appScreen:{
yesText: {
nl: 'Ja',
Expand Down

0 comments on commit 7e0e4f3

Please sign in to comment.