Munna
Munna

Reputation: 207

TypeScript gives warnings on access to object properties

I am working on Angular 4. I was trying to loop object/array using for loop. I am getting output in console but in the build and compile getting errors. Not sure what mistake i am doing.

my data will look like this

let ArrayVal =  [{
       comparator: 'EQ',
       flight: [{
           number: 123
          }, {
           grouping: 'Flight Group South America'
          }]
      }, {
       comparator: 'NEQ',
       flight: [{
           number: 7000,
           endNumber: 7999
          }]
      }];

now i need to fetch numbers from this above data, expected output is numbers = ['123','7000-7999']

so tried something like this

let numbers: any = [];
for ( let val of ArrayVal){
 for (let flight of val.flight) {
    if ( flight.hasOwnProperty('number') && flight.hasOwnProperty('endNumber') ) {
      numbers.push(flight.number + '-' + flight.endNumber );
    }else if  (flight.hasOwnProperty('number')) {
      numbers.push(flight.number);
    }
 }
}
console.log(numbers)

i am getting output as expected in console numbers = [123, "7000-7999"] but issue is getting error in build and compile

TS2339: Property 'endNumber' does not exist on type '{ number: number; } | { grouping: string; }'.
      Property 'endNumber' does not exist on type '{ number: number; }'.
TS2339: Property 'number' does not exist on type '{ number: number; } | { grouping: string; }'.
  Property 'number' does not exist on type '{ grouping: string; }'.

could someone tell me and help me to loop this data. flight.number gives error property number doesnt exist on type '{ number: number; } | { grouping: string; }'

Upvotes: 1

Views: 347

Answers (2)

mohsenmadi
mohsenmadi

Reputation: 2377

Instead of:

for (let flight of val.flight) {
    if ( flight.hasOwnProperty('number') && flight.hasOwnProperty('endNumber') ) {
      numbers.push(flight.number + '-' + flight.endNumber );
    }else if  (flight.hasOwnProperty('number')) {
      numbers.push(flight.number);
    }
 }

You could do:

 for (let flight of val.flight) {
    if ( flight?.number && flight?.endNumber ) {
      numbers.push(flight.number + '-' + flight.endNumber );
    } else if (flight?.number) {
      numbers.push(flight.number);
    }
 }

This is provided that number and endNumber are not 0 just to be sure.

Upvotes: -1

Jota.Toledo
Jota.Toledo

Reputation: 28434

Add any[] to the declaration of ArrayVal.

This happens because TypeScript tries to infer the structure of the objects contained in the array, but it does it wrong as the structure is different on both flight arrays.

Check the following playground

UPDATE:

An even cleaner approach would be to define interfaces for your data (this means actually make use of TS):

interface Data {
  comparator: string;
  flight: Flight[];
}

interface Flight {
  'number'?: number;
  grouping?: string;
  endNumber?: number;
}

let data: Data[] = [{
       comparator: 'EQ',
       flight: [{
           'number': 123
          }, {
           grouping: 'Flight Group South America'
          }]
      }, {
       comparator: 'NEQ',
       flight: [{
           'number': 7000,
           endNumber: 7999
          }]
      }];

let numbers: any = [];

for ( let val of data){
 for (let flight of val.flight) {
    if ( flight.hasOwnProperty('number') && flight.hasOwnProperty('endNumber') ) {
      numbers.push(flight.number + '-' + flight.endNumber );
    }else if  (flight.hasOwnProperty('number')) {
      numbers.push(flight.number);
    }
 }

}
console.log(numbers)

Upvotes: 2

Related Questions