I read a JSON object from a remote REST server. This JSON object has all the properties of a typescript class (by design). How do I cast that received JSON object to a type var?
I don't want to populate a typescript var (ie have a constructor that takes this JSON object). It's large and copying everything across sub-object by sub-object & property by property would take a lot of time.
Update: You can however cast it to a typescript interface!
There is nothing yet to automatically check if the JSON object you received from the server has the expected (read is conform to the) typescript's interface properties. But you can use User-Defined Type Guards
Considering the following interface and a silly json object (it could have been any type):
Three possible ways:
A. Type Assertion or simple static cast placed after the variable
B. Simple static cast, before the variable and between diamonds
C. Advanced dynamic cast, you check yourself the structure of the object
You can play with this example here
Note that the difficulty here is to write the
isMyInterface
function. I hope TS will add a decorator sooner or later to export complex typing to the runtime and let the runtime check the object's structure when needed. For now, you could either use a json schema validator which purpose is approximately the same OR this runtime type check function generatorIn TypeScript you can do a type assertion using an interface and generics like so:
Where ILocationMap describes the shape of your data. The advantage of this method is that your JSON could contain more properties but the shape satisfies the conditions of the interface.
I hope that helps!
TLDR: One liner
The Detailed Answer
I would not recommend the Object.assign approach, as it can inappropriately litter your class instance with irrelevant properties (as well as defined closures) that were not declared within the class itself.
In the class you are trying to deserialize into, I would ensure any properties you want deserialized are defined (null, empty array, etc). By defining your properties with initial values you expose their visibility when trying to iterate class members to assign values to (see deserialize method below).
In the example above, I simply created a deserialize method. In a real world example, I would have it centralized in a reusable base class or service method.
Here is how to utilize this in something like an http resp...
If tslint/ide complains about argument type being incompatible, just cast the argument into the same type using angular brackets
<YourClassName>
, example:If you have class members that are of a specific type (aka: instance of another class), then you can have them casted into typed instances through getter/setter methods.
The above example will deserialize both acct and the list of tasks into their respective class instances.
If you are using ES6, try this:
But this way will not work on the nest object, sadly.