reactjstypescriptreinforced-typings

Typescript Access objects nested within other types


I am relatively new to typescript and it's ins and outs and I am having trouble with a certain structure. it looks like this:

I have a function I am using to feed data to a timeline component. the data recieved by the function can be of type 1 or type 2. Now this is where it gets complicated type 1 is a an object. However, type 2 can be any 1 of 4 different types

type1 : {}

type2 : type3 | type4 | type5 | type6

types 3-6 differ slightly in structure from one another and cannot be combined. In the function below the isConversion flag is a check for an (object: type6). This object has another object inside it of type 7.

type 6: {
   ...,  
   type7: {
       ...,
       conversions
   }
}

inside type7 is a field called conversions that has the data I need to pass to the timeline.

timelineItems = (items: type1 | type2): PropsData => {
    const { dataType, isConversion } = this.state

    if(isConversion){
      const {comments, type7.conversions } = items as type6
      return {
        comments
        type7.conversions
      }
    }

I have a work around where I fetch type7 when I get the data and set it to the state. and use that value but I would like to to know if there is a way to get the conversions object as above.

Thank You.


Solution

  • So you want to know if you can determine if items type is Type6?

    Typescript types are lost after compilation so you have to write your own typeguard which will return true if object is Type6. It's pure javascript check, for example if you know that only Type6 has certain field you can check if it is present in this object.

    interface Type6 {
      comments: any[];
      type6: Type7;
    }
    
    interface Type7 {
      conversions: any[];
    }
    
    function isType6(obj): obj is Type6 {
      return obj.type6 !== undefined;
    } 
    

    Then you can use this typeguard like this:

    if(isType6(items)) {
      const {comments, type6: {conversions}} = items; // no cast needed, ts know it is Type6
      return {comments, conversions };
    }