Declarative / lazy API
Closed this issue · 3 comments
Currently intl-codegen
creates two different APIs:
- a direct imperative API based on function calls
- a declarative / lazy API specifically for react
It would be nice to combine the best of these two worlds, which should actually be quite straight-forward.
The react types already generate a big union type which has all the translations as data:
type LocalizedType =
| {
id: "foo",
}
| {
id: "bar",
params: { param: string },
}
We can expose this generic data-type more directly, and expose a function which can consume it in a type-safe way.
I see two ways to do this without a backwards incompatible break:
- make
IntlObject
a function. So you can do:
const intl = await loadLanguage(locale);
return intl({ id: "bar", params: { param: "foobar" } });
- attach such a function to the
context
, maybe viaintl.context.translate({ id: "bar", params: { param: "foobar" } })
I definitely like the first approach better.
One important thing would be to bikeshed the exported name of this… Suggestions welcome…
BTW, a bit related to this, but I have been brainstorming for quite some time how to best do such a stricty-typed codegen project for Rust, and the idea I had also came very close to this:
enum Translation
Foo,
Bar { param: String },
}
trait Intl {
pub fn translate(translation: &Translation) -> String;
}
or something similar to this…
That way, you can completely split up the what you want to translate, and how to actually translate it. With plain data as the interface.
Nice one!!!
- I would prefer
TranslationKey
instead ofLocalizedType
. - Since
intl.translate
is not possible because it is possible that there is a translation calledtranslate
, i would prefer the first solutionintl(translationKey: TranslationKey)
.
Very nice! Thanks arpad!
Nice code and tests as always :).