'i18next: Map an array of objects in TypeScript
I am rewriting a React project to TypeScript.
Packages: Next.js, next-i18next, styled-components
EDIT:
The answer is outdated as of current next-i18next
versions.
Please refer to: Typescript i18next does not satisfy the constraint 'string | TemplateStringsArray NextJS
Quick Example:
{t<string, ItemProps[]>('document.items', {returnObjects: true}).map(({ name, description, index }) => (
<li key={index}>
<strong dangerouslySetInnerHTML={{__html: name}} />
<Paragraph dangerouslySetInnerHTML={{__html: description}} />
</li>
)
)}
I also made a codesandbox for this solution.
Original Question:
I used an array of objects in a language json file:
{
"websites":
[
{
"slug": "website-a",
"name": "Website A"
},
{
"slug": "website-b",
"name": "Website B"
}
]
}
List all of them with i18next's { t }
:
t('websites', {returnObjects: true}).map(({slug, name}) => ( ... ))
TypeScript underlined map
:
Property 'map' does not exist on type 'string'.
Rewrote this with TypeScript:
type websiteProps = {
map: Function;
};
type itemProps = {
slug: string;
name: string;
};
t<websiteProps>('websites', {returnObjects: true}).map(({slug, name}: itemProps) => ( ... ))
This worked but I was wondering if I just 'put out' underlines for .map
.
Is there anything better I could do?
Thank you!
Solution 1:[1]
I don't know much about i18, but try using this instead:
t<itemProps[]>('websites', {returnObjects: true}).map(({slug, name}: itemProps) => ( ... ))
This tells TypeScript that t
will return an array of itemProps
.
I was wondering if I just 'put out' underlines for
.map
You should almost never suppress TypeScript's compiler errors. However, if you really must you can use // @ts-ignore
on the line above.
Solution 2:[2]
@cherryblossom's answer is correct - I am posting as a new answer to help provide a bit more details.
Here is the basic i18n t function's type definition (used by your code):
<
TResult extends TFunctionResult = string,
TKeys extends TFunctionKeys = string,
TInterpolationMap extends object = StringMap
>(
key: TKeys | TKeys[],
options?: TOptions<TInterpolationMap> | string,
): TResult;
It's a generic function which can take TResult, Tkeys and TInterpolationMap as the options. As we can see, when called without any type parameters, TResult defaults to "string".
string type doesn't have .map function hence the error.
Since you are sure you should be getting an array of items back, you need to specify the TResult type parameter explicitly, like @cherryblossom indicated:
t<itemProps[]>('websites', {returnObjects: true}).map(...)
BTW, the type definitions for the libraries you are using are super useful when trouble shooting any issues like this. Please always check that first for such scenarios.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | cherryblossom |
Solution 2 | Dharman |