#Dealing with 2 similar objects

1 messages · Page 1 of 1 (latest)

terse stirrup
#

Hello! I have a question that is a little more typescript centric than angular, but I was wondering what the best way to handle this situation is.

I have 2 interfaces, ProposalCoupons and LiveCoupons. They are very similar in structure.

interface ProposalCoupons {
  reimb: number;
  retail: number;
  frequency: number;
  percent: number;
}

interface LiveCoupons {
  reimb_amount: number;
  retail_amount: number;
  percent: number;
}

These come from the API as an array of these objects.

I have a component that I want to be able to accept either of these, and do some aggregations using the data.

@Component({ ... })
class CommissionsComponent implements OnInit {
  @Input() coupons: ProposalCoupons[] | LiveCoupons[];

  ngOnInit() {
    // use this.coupons and be able to access the data in a generic way, for example:
    // this.coupons.reduce((acc, c) => acc += c.reimb * c.percent, 0);
  }
}

How should I go about this? I looked into using class-transformer, but i'm not sure its able to do this sort of thing.

#

I agree that these objects being different in structure is not ideal, but changing them would require sweeping changes across our system which is not worth it at the moment

tight monolith
#

Isn't the code you posted working as you expect it to? You are accepting both types and should be able to do the this.coupons.reduce((acc, c) => acc += c.reimb * c.percent, 0); part?

limber needle
#

you could use a typeguard

function isProposalCoupons(coupon: LiveCoupons | ProposalCoupons): coupon is ProposalCoupons {
  return (coupon as ProposalCoupons).reimb !== undefined;
}

function isLiveCoupons(coupon: LiveCoupons | ProposalCoupons): coupon is LiveCoupons {
  return (coupon as LiveCoupons).reimb_amount !== undefined;
}

export class CommissionsComponent implements OnInit {

  @Input() coupons: ProposalCoupons[] | LiveCoupons[] = [];

  ngOnInit() {
    const reimb: number = this.coupons.map(v => {
      if (isProposalCoupons(v))
        return {reimb: v.reimb, percent: v.percent};
      else 
        return {reimb: v.reimb_amount, percent: v.percent};
    }).reduce((acc, c) => {
        return acc += c.reimb * c.percent; 
    }, 0);
  }
}
#

or an intersecting interface

    this.coupons.map(v => {
      return v as ProposalCoupons & LiveCoupons
    }).reduce((acc, c) => {
      return acc += (c.reimb ?? c.reimb_amount) * c.percent;
    }, 0);
terse stirrup