1

Given the following classes

class A {
   constructor(){
      this.name ="Some name";
    }
  name:string;
}

class C extends A {
  
  get Age() {
    return 21;
  }

  SayHello(){
      return "Hello";
  }
  
}

If you would to build the OBJECT from a JSON Parse

var demo2:C= JSON.parse('{"name":"Joan of Arc"}') AS C;

This will not work:

console.log(demo2.Age);
console.log(demo2.SayHello());

Any workaround or ideas?

1
  • 2
    There is no casting in TypeScript! The as (or <> syntax) is a type assertion. You just override the compiler and tell it "regardless of what you think this thing is, not consider it this other thing. Just trust me". That doesn't actually change anything about the object, simply stops compilation errors, not runtime ones. So, if you have object of one shape and want it in another, you have to change it yourself. With classes the usual way is to accept an object in the constructor or otherwise initialise the class instance via an object. Commented Nov 16, 2020 at 19:32

2 Answers 2

1

It doesn't work because Typescript doesn't cast JS objects, meaning that it doesn't change or modify them, it's only used for types. So when you use as statement, demo2 is being treated by Typescript as instance of C, while in reality demo2 isn't instance of C. To make it work you can modify C so it has a constructor which accepts an object and assigns its properties to this

// add this to the body of C
constructor(obj: C) {
 Object.assign(this, obj);
}
// later in code
const demo2 = new C(JSON.parse('{"name":"Joan of Arc"}') AS C);

Sign up to request clarification or add additional context in comments.

Comments

1

JSON.parse(...) as AnyClass will not (cast) or create the object AnyClass.

One clever solution are:

const parsedJson = JSON.parse(...)
const myObj = new AnyClass();
Object.assign(myObj, parsedJson);

4 Comments

It's not very clever but very dangerous, as you have no idea what you're overwriting on myObj. Consider this. You can easily malform your object and the compiler will let you shoot yourself in the foot.
This is not a type safe solution. I say that is clever, because it's simple and some danger, but not very much danger. Json.parse garanting that the object not have functions on it, and then, only assign attributes. If you pass some strange Json your code will not run or typescript assert what attributes you specified to this class, and ignores strangers ones.
Yes, the object will not have functions but you don't know what it has. You could write a string where a boolean is expected. Or an array, where a number should be. Moreover, you don't know which values are missing. It's short, true, but it makes your maintenance a nightmare. Sure, getting all the properties you know and defaulting them is longer but you really only need to write that code once. And you'd know you don't get into weird states afterwards. The clever thing in programming is not to save yourself work now but to save future work.
Of course, to work with jsons it's nice use some assetion library, in javascript as well as typescript.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.