I'm using this object format to store translation strings for multiple languages:
export const Translations = {
'en': {
text1: 'Hello world!',
text2: 'Login'
}
'cs': {
text1: 'Ahoj svět!',
text2: 'Přihlášení'
}
}
Then I have my state and an interface for the state defined:
export const MyState: State = {
lang: 'cs',
trans: Translations.cs,
}
export type State = {
lang: LangCodes,
trans: ???
}
Now I would need somehow to define that MyState.trans
can contain only names of translation properties, which means text1, text2
in this case. Something that enables type checkings an autocomplete feature in editor for this object (when using like this: MyState.trans.text1
). Can it be done?
I believe union of all possible/allowed state should help:
export const Translations = {
'en': {
text1: 'Hello world!',
text2: 'Login'
},
'cs': {
text1: 'Ahoj svět!',
text2: 'Přihlášení'
}
} as const
type Translations = typeof Translations
type LangCodes = keyof Translations
type Values<T> = T[keyof T]
// Make union of all allowed states
type Union = {
[P in LangCodes]: {
lang: P,
trans: Translations[P]
}
}
// get all values of the union
type State = Values<Union>
export const MyState: State = {
lang: 'cs',
trans:Translations.cs
} // ok
export const MyWrongState: State = {
lang: 'cs',
trans:Translations.en
} // error
P.S. My main goal is to make invalid state unrepresentable