Home > Net >  How to use Object.entries with map([key,value]) with TypeScript properly
How to use Object.entries with map([key,value]) with TypeScript properly

Time:10-31

I'm learning React with TypeScript and i need to transform my response data into one object.

I wrote code which works without typescript. Could you tell me how to do it with type safety?

From response i receive following data:

 {
        "-MnI78G4UBVNSdurDCQK": {
            "amount": 1,
            "id": 1,
            "image": {
                "url": "https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-13-pro-family-hero?wid=940&hei=1112&fmt=png-alpha&.v=1631220221000"
            },
            "name": "iPhone 13 Pro",
            "price": 5299
        },
      

  "-MnI78IKVgJnmF_8XTZ6": {
        "amount": 2,
        "id": 2,
        "image": {
            "url": "https://cdn.x-kom.pl/i/setup/images/prod/big/product-new-big,,2019/7/pr_2019_7_17_13_43_4_952_00.jpg"
        },
        "name": "Macbook Air M1 16gb 512gb",
        "price": 7999
    }
}

By using object.entries i'm transforming data like this:

const transformedData = Object.entries(data).map(([key, value]) => {
      return {
        ...value,
        id: key,
      };
    });

And it's working but without type safety.

CodePudding user response:

If the data is coming from an external source, then your code can't know it's type for sure. This is why JSON.parse(myJson) returns the type any.

But if you are reasonably sure what for the server returns you can write your own type and cast your data to that type.

The type of each item in that response looks something like:

interface MyItem {
  amount: number
  id: number
  image: { url: string }
  name: string
  price: number
}

And then the api returns those in an object with string keys:

type MyApiResponse = { [key: string]: MyItem }

And lastly, you just need to tell typescript that you, the programmer, know what type this data really is with a cast:

const transformedData = Object.entries(data as MyApiResponse).map(([key, value]) => {
  return {
    ...value,
    id: key,
  };
});

const test = transformedData[0].image.url // string

Playground

CodePudding user response:


interface Data {
    amount: number,
    id: number,
    image: {
        url: string
    },
    name: string,
    price: number
}

interface DataMap {
    [key:string]: Data
}

const data:DataMap =  {
        "-MnI78G4UBVNSdurDCQK": {
            "amount": 1,
            "id": 1,
            "image": {
                "url": "https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-13-pro-family-hero?wid=940&hei=1112&fmt=png-alpha&.v=1631220221000"
            },
            "name": "iPhone 13 Pro",
            "price": 5299
        },
      

  "-MnI78IKVgJnmF_8XTZ6": {
        "amount": 2,
        "id": 2,
        "image": {
            "url": "https://cdn.x-kom.pl/i/setup/images/prod/big/product-new-big,,2019/7/pr_2019_7_17_13_43_4_952_00.jpg"
        },
        "name": "Macbook Air M1 16gb 512gb",
        "price": 7999
    }
}

You can use given interfaces to describe your data structure.

  • Related