i18next / i18next-parser

Parse your code to extract translation keys/values and manage your catalog files
MIT License
485 stars 197 forks source link

Parse namespace from `t` type arguments #703

Closed ggalletty closed 1 year ago

ggalletty commented 1 year ago

πŸš€ Feature Proposal

Extract namespace from t type definition.

Motivation

This feature would extend the current javascript lexer to check for type arguments of TFunction, allowing the parser to set a default namespace for cases where the translation function is passed as param to other functions.

Example

// component.tsx
const Component = () => {
  const { t } = useTranslation("foo");
  const templateData = useMemo(() => getData(t), [t]);
  return <UserProfile help={t("bar")} content={templateData} />
};

// helper.ts
const getData = (t: TFunction<"foo">) => ({
  greeting: t("baz"),
})

With the proposed feature, we would parse the function declarations to extract namespace from type arguments of t so that all parsed keys (bar and baz) end up in foo namespace even though there was no namespace function used in helper.ts.

In the case above, let's suppose we have multiple instances of i18next per context, for this reason we can't just use the global i18next.t in the helper.

mijamo commented 1 year ago

I am also looking for this, is there currently a workaround that you are aware of?

For information, my use case is to have a single file collecting all the form error messages separated from the different form components here and there, and having something a bit like the helper.ts in this example was the most obvious way to have it working, but because of that all the error messages end up in the default namespace.

ggalletty commented 1 year ago

Hey there @mijamo!

As workaround you could configure the lexer to use a custom namespaceFunction which accepts a namespace as parameter. The parser will assign that parameter as default namespace for the whole file. That function could return the a t function with the right namespace (see getFixedT for that).

That will work fine as long as you have a single instance of i18next. When you have multiple instances, you will most likely pass the t around and that's where this feature comes truly handy.

As only alternative to that final use case, which is my particular case, you can either use an empty namespace function in addition to passing the t around OR just repeat {ns: "foo"} in every translation call.

Good luck with that! 🀞

ggalletty commented 1 year ago

hi @karellm! bumping this in hopes we can review it and hopefully merge related change request 🀞

i believe this would be a practical way to enable us to parse namespaces properly without the need of using namespace functions

karellm commented 1 year ago

This is published as 7.3.0