简体   繁体   中英

Cast object type to another type

I have class where I set type of range to IntervalRange

export class Test {range: IntervalRange;}

then in parent class I initialize the value:

export class TestInitializer {
Create(){
    return <Test>{
        range: IntervalRange.initialize(Database.GetByName('MONTH').id};
}

InitializeElement() {
  let test = <Test>JSON.parse(JSON.stringify(configuration));
  return test;
}

then in my other component I use this as:

@Input() range: IntervalRange;

However on function range.getRange(); I get: ERROR TypeError: this.range.getRange is not a function

Why is that? it says range is an Object, though it should be IntervalRange .

I tried writing as IntervalRange , <IntervalRange> range nothing worked. How to fix that?

Update: let type = typeof(this.range) ; prints "object"

method:

ngOnChanges() {
if (this.range) {
  let type = typeof(this.range);
  let ddd = this.range.getRange(); //<----- this is where I get error
}

A typecast only casts the type. Typescript doesn't exist at runtime. Therefore if JSON.parse doesn't return a proper Test instance (which it won't since methods won't get serialized), it will fail at runtime. Instead of typecasting you probably want to build up a Test instance, and load the serialized data into it.

The TypeScript "cast" ( <A>tmp or tmp as A ) :

  • makes structural type compatibility checking → it is unavailable if the source data has type any .
  • has no runtime counterpart → TypeScript types can be compatible but runtime types can differ, for instance an object literal vs a real class instance.

When the data comes from an unsafe/external source, eg JSON.parse() or a WebAPI call, it's a DTO (data transfer object) , with the any type. The TypeScript "cast" is unsafe too.

To ensure the cast operation, you can use a mapping function from the DTO to the "domain model" class. The key point is to return a real class instance.

  • Object.assign(new IntervalRange(), this.range) (that you mentioned in a comment) satisfies this point.
  • We can be even more stricter with a "field by field mapping": this.a = range.a; this.b = range.b; ...) this.a = range.a; this.b = range.b; ...) this.a = range.a; this.b = range.b; ...) .

Both options are better encaspulated in a function: the class constructor, a static factory method in the class, an external function in the same module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM