-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Take fallbackNs into consideration for TFunction key type check #1268
Comments
Hey @Haaxor1689, thanks for pointing that out. const { t } = useTranslation<'foo'>(); I'll be adding that to the documentation. Regarding the second case, you don't need to override the const { t } = useTranslation('goo'); And it's behaving as expected, it'll accept I've created this example to illustrate that. |
The provided example is missing the |
Ohh sorry, I fixed it, thanks! The idea of this example is to show the types working 😄 |
Few more issues:
After that is fixed you can see that everything in |
Also now that you mention it, this should also not give an type error since it gets translated. // "foo" is a `defaultNS` in this case
const { t } = useTranslation<"foo">();
t("foo:a"); |
Hey @Haaxor1689, when relying on type augmentation to infer keys and return type, this format will only work when loading multiple namespaces like this (array format): |
I updated the example, thanks! |
Ok I think my use case was not following the ideology of how the namespaces should be used. By specifying If this is the case then those type checks giving errors are correct even though the translations are found during runtime. Still there is the const resources = {
en: {
moduleA: { keyA: '...' },
moduleB: { keyB: '...' },
common: { cancel: '...' },
}
}
i18next.use(initReactI18next).init({
resources,
lng: 'en',
ns: Object.keys(resources.en),
fallbackNS: 'common',
});
// Component in "module a"
const ComponentA = () => {
const { t } = useTranslation('moduleA');
console.log(t('keyA'), t('cancel'));
}
// Component in "module b"
const ComponentB = () => {
const { t } = useTranslation('moduleB');
console.log(t('keyB'), t('cancel'));
} Is that correct? If so then keys from |
Hey @Haaxor1689, sorry for the delayed response, it's been a very busy week. Basically, by relying on the typescript to infer the keys and return types, you wouldn't need a import 'react-i18next';
import moduleA from 'locales/en/moduleA.json';
import moduleB from 'locales/en/moduleB.json';
import common from 'locales/en/common.json';
declare module 'react-i18next' {
interface Resources {
moduleA: typeof moduleA & typeof common;
moduleB: typeof moduleB & typeof common;
common: typeof common;
}
} |
This workaround works like a charm :) type MapFallback<T, Fallback extends keyof T> = {
[key in keyof T]: T[key] & T[Fallback];
};
declare module 'react-i18next' {
// eslint-disable-next-line
interface Resources extends MapFallback<typeof resources['en'], 'common'> {}
} |
But this has an unexpected behavior when removing the default namespace from the |
🐛 Bug Report
When using the method of redeclaring
Resources
to provide type check forTFunction
the generated keys also contain namespace that is not a fallback one which results in typescript being ok with a key that doesn't resolve into a translation.To Reproduce
With this setup none of these usages show a type error:
Another issue with key type check arises when you specify a namespace in
useTranslate
hook.Expected behavior
Add option to also specify which of the namespaces are also fallback namespaces so keys of non fallback namespaces don't pass through type check in TFunction.
Your Environment
The text was updated successfully, but these errors were encountered: