first time posting a question.
So my problem is that I want to define an object for storing strings in different languages. This needs to be flexible so the best I've come up with is a nested object structure, but I want the last object to be a specific type or interface.
At first I tried:
interface Text {
[key: string | number]: ComponentText | Language;
}
interface Language {
[key: string]: string;
}
text: Text = {
title: {
en: "English text",
sv: "Swedish text",
fr: "French Text",
es: "Spanish Text",
}
paragraph: {
subText: {
en: "English text",
sv: "Swedish text",
fr: "French Text",
es: "Spanish Text",
}
}
}
// getCurrLang(s: any) handles getting the correct language string or throws an error when "s" isn't "Language".
But I'm getting errors when I try to retreive the getCurrLang(text['paragraph']['subText'])
saying:
Argument of type 'string | Text | Language' is not assignable to parameter of type 'Text | Language'. Type 'string' is not assignable to type 'Text | Language'.
This is something I've come up with that I thought would solve the problem, but unless the key value can contain the same as "language" this doesn't work and solves nothing:
type LangCode = 'en' | 'sv' | 'fr' | 'es';
interface Text {
[key: string]: ComponentText | Array<ComponentText>;
language?: Language;
}
type Language = {
[key in LangCode]: string;
};
Is there a way to define this type of structure or something better?
The problem was caused by the way we tried to the nested objects.
Even with the type definition from @David Culberth TypeScript requires the use of type narrowing when it is of a union type ComponentText | TextTranslation
And can not be retrieved by a simple getCurrLang(text['paragraph']['subText'])
To fix this I extended the getCurrLang(s: any)
as such:
public getLangString(
s: ComponentText | TextTranslation,
selector?: Array<string>
): string {
if (this.isTextTranslation(s)) {
return s[this.getLanguage()];
} else if (this.isComponentText(s) && selector) {
return this.getLangString(
s[selector[0]],
selector.length > 1 ? selector.slice(1) : undefined
);
}
return 'error: ' + s + 'is not of type TextTranslation or ComponentText';
}
So the retrieving now looks like this getLangString(text, ['paragraph', 'subText'])