I am consuming an api that returns nested json. It is dynamic so the keys will often be different. What can be guaranteed is that the key and value will always be a string.
Here is an example:
const response = {
name: 'Pete',
location: 'London',
age: {
year: '21'
}
}
I have tried type it like this:
type Response = {
[key: string]: string
}
Then in a React component I want to use it like this:
type Response = {
[key: string]: string
}
const Foo = ({ data }: Response) => {
return <pre>{JSON.stringify(data, null, 2)}</pre>
}
This gives me the following error:
Property 'x' does not exist on type 'string'
Can anyone point me in the right direction here?
here is a link to stackblitz - https://stackblitz.com/edit/react-ts-4n7vcy?file=App.tsx
CodePudding user response:
What you are doing is assigning the type Response
to the props argument of your Foo
functional component. So actually, the Foo
component accepts a props object with the type of Response
, but the data
variable is inferred as a string by typescript. What you should do instead is;
interface IFooProps{
data: Response;
}
const Foo = (props: IFooProps) => {
return <pre>{JSON.stringify(props.data, null, 2)}</pre>;
};
CodePudding user response:
The issue is that the values in your type are strings. When you extracted the data
key its type was a string. You either need to type it like:
type Response = {
data: {
[key: string]: string
}
}
Or accept it in the component like
const Foo = (data: Response) => {
// ...
}
If you want the values to be either string or nested objects, you can do:
type Response = {
[key: string]: string | Response
}
And then the data
in your example will be of type string | Response
.