react-i18next: Undefined as a return type for t from useTranslation is not allowed as React Element
Describe the bug When you use the t function returned from useTranslation() in jsx, react/typescript will complain that undefined is not a valid JSX element type.
That is, because TFunction returns TResult and TResult can be undefined
type TFunction = <
TResult extends string | object | Array<string | object> | undefined = string,
TKeys extends string | TemplateStringsArray = string,
TInterpolationMap extends object = StringMap
>(
key: TKeys | TKeys[],
options?: TOptions<TInterpolationMap> | string,
) => TResult;
Occurs in react-i18next version 10.5.2
To Reproduce
function MyComp() {
const {t} = useTranslation();
return (<span>{t('')}</span>);
}
Expected behaviour Using t directly in JSX should work according to docs: https://react.i18next.com/latest/usetranslation-hook
OS (please complete the following information):
- Device: Mac Mini
- Browser: Chrome
- Typescript: v 3.3.4000
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 16 (2 by maintainers)
First off, sorry to raise up a question in such an old issue.
However, I’ve stumbled over this issue (in combination with [1]) and I suspect the nullish inference is just for convenience. Right off the bat, I don’t see any obvious place where translate would ever return undefined (looking at [2]) which leads me to think that the type signature is incorrect as it doesn’t reflect the actual implementation.
This could potentially result in undefined behavior and bugs, provided that the consumer expects these strict types. In fact, similarly, I don’t see any way either to distinguish string outputs from object/array outputs (as is tested here: [3]). You would need runtime information to determine if it’s the prior or the latter.
While I’m aware the
TFunction
-interface would need to change to be completely safe at runtime. I’d argue, the user should have to indicate which particular translations return objects and/or arrays. Something along the lines:As a quick fix to my actual problem I would have to augment
TFunction
with this overload, such that it will prioritized over the second signature (note the changedTResult
):Now, I just hope that no colleague of mine modifies the translations into an object based translation, resulting in
[object Object]
😛edit:
I guess you already support
returnObjects
which can provide some inference, but it breaks everything if it’s configured globally. At least it’s far more difficult to infer that part as there’s a global client that the user doesn’t control the initialization of and cannot easily pass around. He/she would have to mutate the client using theinit
interface and expose that mutated client as a cast version which enforces thereturnObjects
-based interface.Here’s an inferrable version of
TFunction
that’s more flexible. Again, this is not correct ifreturnObjects
is configured globally:I don’t remember what I did, but now I don’t have this issue anymore
good question - in my world i don’t get an undefined back from t - all i get is an empty string when calling with empty string as key…so would be nice to reproduce this…but for that i would need more informations
but guess this is more a warning of typescript (than the javascript truth of code)
@enoh-barbu and @tonghe7 this issue is old and there are so many changes that the content is likely not relevant. If you want to know how to setup either typescript or the usages of it, just check this repo’s tests and tsconfigs.
this still doesn’t work for me and I don’t understand, what’s the fix/solution?
“i18next”: “^21.4.0”, “react-i18next”: “^11.13.0”,