Home > Software engineering >  How to add new type to a nested types
How to add new type to a nested types

Time:01-22

I've been trying a lot with this problem without any solution.

The problem: I retrieve a large object from an API. I have to add more properties to this object, everytime I pass this object to a function that adds new properties the type of the object changes because new properties were added. I'm not sure if what I'm doing is the best way to do this, so let's see:

I have these types declared:

export type Match = {
  metadata: Metadata;
  info: Info;
};

export type Info = {
  participants: Participant[];
};

export type Participant = {
  item0: number;
  item1: number;
  item2: number;
  item3: number;
  item4: number;
  item5: number;
  item6: number;
};

export type ItemsAsset = {
    itemAsset0: string;
    itemAsset1: string;
    itemAsset2: string;
    itemAsset3: string;
    itemAsset4: string;
    itemAsset5: string;
    itemAsset6: string;
  };

The object I retrieve:

{
    "metadata": {
        "dataVersion": "1",
        "matchId": "1",
        "participants": [...]
    },
    "info": {
  // more properties
        "participants": [
            {
 // more data
                "item0": 6665,
                "item1": 4637,
                "item2": 3116,
                "item3": 3009,
                "item4": 3024,
                "item5": 3082,
                "item6": 3363,
            }
            // more participants data
        ]
    }
}

after passing this object to the first function that add properties:

{
    "metadata": {
        "dataVersion": "2",
        "matchId": "",
        "participants": [...]
    },
    "info": {
  // more properties
        "participants": [
            {
 // more data
                "item0": 6665,
                "item1": 4637,
                "item2": 3116,
                "item3": 3009,
                "item4": 3024,
                "item5": 3082,
                "item6": 3363,
                "itemAsset0": "http://img/item/6665.png",
                "itemAsset1": "http://img/item/4637.png",
                "itemAsset2": "http://img/item/3116.png",
                "itemAsset3": "http://img/item/3009.png",
                "itemAsset4": "http://img/item/3024.png",
                "itemAsset5": "http://img/item/3082.png",
                "itemAsset6": "http://img/item/3363.png",
            }
            // more participants data
        ]
    }
}

"ItemAsset" is the new type that needs to be added to a new type declaration for the new object, if I do:

export type MatchWithItemAssetInParticipant = Match & ItemAsset;

It doesn't work, and also needs to be inside "Participant" type. If I do:

export type MatchWithItemAssetInParticipant = Match & ParticipantItemAsset;

export type ParticipantItemAsset = Participant & {
  itemAsset0: string;
  itemAsset1: string;
  itemAsset2: string;
  itemAsset3: string;
  itemAsset4: string;
  itemAsset5: string;
  itemAsset6: string;
};

It doesn't work neither, seems like I can't make changes inside Match type. Hope I was clear. Thanks in advance!

CodePudding user response:

You can make the Info type generic (and subsequently the Match type), which allows you to specify the type of participants:

export type Info<P = Participant> = {
  participants: P[];
};

export type Match<P = Participant> = {
  metadata: Metadata;
  info: Info<P>;
};

Now you can specify the altered participant data:

function loadMatch(): Promise<Match>; // or Promise<Match<Participant>> if you want to write it out
function addParticipantItemAssets(match: Match): Match<Participant & ItemsAsset> 

When you update the values in your function, typescript will complain, because you will treat Match with regular participants like Match with Participant & ItemAsset at some point. In that case, use as to tell it what kind of object it should think you work with:

function addParticipantItemAssets(match: Match): Match<Participant & ItemsAsset> {
  return match as Match<Participant & ItemsAsset>
}
  • Related