1

I'm trying to add a computed property to a array of typed objects I'm getting (from a server).

I've built a simplified example that i think is similar to my case:

in this example, I'm trying to use a property of ClassA to cucullate a property and add it to ClassB, and when i'll have objects of type ClassA I could hopefully cast them to ClassB, and the required property will be calculated and added to it.


export class ClassA {
  title = 'a1';
}

export class ClassB extends ClassA {
foo(){
  return this.title+'a';
}
  someProperty = this.foo();
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'classExtenstionTest';
    x = new ClassA;
    xx= this.x as ClassB; //can i do this?

 ngOnInit() {
  console.log(this.x);// return properties of class A
  console.log(this.xx); //also returns properties of class A (and not ClassB), why?
  }
}  

but it doesn't seem to work, I cant get the required properties of ClassB after the casting. I'm fairly new to typescript, any help will be appreciated, thanks!

Alex K
  • 61
  • 6

2 Answers2

1

The as keyword in TypeScript is not doing what you think it is. It is only syntax for the transpiler to ignore type checking and not "casting" like in Java for instance. A better explanation of as in TypeScript here: https://stackoverflow.com/a/55781571/4529555


There are many different ways to achieve what you want.

Why not use the constructor of ClassB and pass the concrete instance of ClassA?


export class ClassA {
  title = 'a1';
}

export class ClassB extends ClassA {
constructor(objectA: ClassA) {
    super();
    this.title = objectA.title
}
foo(){
  return this.title+'a';
}
  someProperty = this.foo();
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'classExtenstionTest';
    private x = new ClassA();
    private xx= new ClassB(this.x);

 ngOnInit() {
  console.log(this.x);
  console.log(this.xx);
  }
}  
Robert Rendell
  • 1,658
  • 15
  • 18
  • thank you for the explanation of the "as" keyword. but what if I got an array of objects of ClassA? should I iterate on a for loop giving each member of ClassB an instance of ClassA? or is there a better way? – Alex K Mar 26 '23 at 19:57
  • 1
    `ClassB` is effectively a wrapper class for `ClassA`. A better way would be to parse the server output directly into `ClassB` and remove the need for `ClassA` in `AppComponent`. Yes looping over each `ClassA` object instance seems like the way to go if you want to use a wrapper. – Robert Rendell Mar 26 '23 at 20:41
1

The reason why you're not seeing the properties of ClassB after casting x to ClassB is because xx is still referencing the same object as x, even after the cast. Therefore, the properties of xx will be the same as the properties of x.

To create a new ClassB object with the same properties as x, you can create a new instance of ClassB and set its properties to match those of x.

Please check this ts playgr

AnwarMEQOR
  • 51
  • 4
  • Didn't work [ts playgr](https://www.typescriptlang.org/play?ssl=34&ssc=4&pln=1&pc=1#code/MYGwhgzhAEDC5QILQN4ChrQC4EssgFNoBeaAcjAEYyBuNAXzVEhnhYCFoCAPLAgOwAmrBBGTpMAMwD20gBQBKVBkzQATgSwBXNf2wALHBAB0ufEQDU5MLRWMVEaQFsCABTXSADgTVYAniQGRsYy8gp0mGaEgWQARtQ00AD0SdDSAG4+ajiCRFj6eXjRnh7evn4MaEyi0IienrDOntL8AljKkUVEpGTMUACivAIQuC0AKgQjtpjcga0A7nCiiIoR0NyzpPnBs5BLHHQq-ADmAPL8AJL8eIodqsAtjoTGINLHctsm3OHJqRrauhgKCiBAAXNZqIxVNAHvwngQXm8PoYvt9Eil1JodHDUCDwXFqAAaaCOFzuLw+fz4+I2KHQRj2WEjaBgcF1BpNFptOYERbsxpOZqtfhYVZVMDGE7nK43cJoJIAKgVGAV0AA2gAZU4AcQAuuC2EhwRJVZgAEQgs3gs1UM0q+nQe2anX6-ZGjqm6AWrpWr22+30TAqpJAA) – Robert Rendell Mar 26 '23 at 20:30
  • @RobertRendell I'm sorry, I guess I misunderstood the question. Please check the updated answer. – AnwarMEQOR Mar 26 '23 at 20:50