Reputation: 16729
I am trying to figure out if a Typescript
object is same as a Javascript
object. I have a typescript
variable into which I want to typecast result of JSON.parse
which I suppose creates a javascript
object
from a json
but I am unable to do it.
I have the following two classes
export class User {
constructor (public firstname:string,
public lastname:string,
public email:string,
public password:string=""){}
}
export class UserProfileAPI {
'external-profile': User;
constructor(externalProfile:User){
this['external-profile'] = externalProfile;
}
}
I have created a spec to test that an object
created explicitly is same or similar to object created by json.parse
but they don't seem to be.
fit('should test if Typescript object is same as Javascript object',()=>{
let user = new User('manu','chadha','[email protected]');
let dummyUserProfile:UserProfileAPI= new UserProfileAPI(user);
console.log('dummy profile is ',dummyUserProfile);
let dummyProfile2:UserProfileAPI = JSON.parse('{"external-profile":{"firstname":"manu","lastname":"chadha","email":"[email protected]"}}');
console.log('dummy profile 2 is ',dummyProfile2);
console.log('dummy profile1 == dummy profile 2',(dummyUserProfile == dummyProfile2));
console.log('dummy profile1 === dummy profile 2',(dummyUserProfile == dummyProfile2));
expect(dummyUserProfile).toEqual(dummyProfile2);
expect(dummyUserProfile).toBe(dummyProfile2);
});
In the above case, dummyUserProfile
is printed as LOG: 'dummy profile is ', UserProfileAPI{external-profile: User{firstname: 'manu', lastname: 'chadha', email: '[email protected]', password: ''}}
but dummyProfile2
is printed as LOG: 'dummy profile 2 is ', Object{external-profile: Object{firstname: 'manu', lastname: 'chadha', email: '[email protected]'}}
and both the comparisons return false
. Why?
Upvotes: 1
Views: 1349
Reputation: 52133
First of all, as several others have already said in comments: in JS objects never ==
or ===
unless they are the same reference. Equality by value doesn't work, ie {} == {}
is always false. But given an object like const obj = {}
then obj == obj
is true. This has nothing to do with TypeScript.
Now to this part of your question:
I am trying to figure out if a
Typescript
object is same as aJavascript
object. I have atypescript
variable into which I want to typecast result ofJSON.parse
which I suppose creates ajavascript object
from ajson
but I am unable to do it.
Two important things here you should understand:
What you are calling a "TypeScript object" and a "JavaScript object" is really a JavaScript object constructor (or instance of) and a plain JavaScript object. Again this has nothing specifically to do with TypeScript. In ES6 you can define class
object types and even in ES5 you can with an old-school constructor function.
What you call a "typecast" in TypeScript is really just a type assignment (or you may have tried a type "assertion"), meaning it does not change the object in any way, it just informs the compiler what you assume the type of the object should be. You can assign any
to any type, but it doesn't mean it's true. There's actually a lot of ways you can break your code by writing wrong type assignments and assertions.
So your real issue is that JSON.parse()
gives you a plain JS object and you want to turn it into a JS object type instance. There's no built-in way to do this in JS unfortunately but of course you can manually do it after decoding the JSON. See: Parse JSON String into a Particular Object Prototype in JavaScript
A simple example in your case might look like this:
function decodeUserFromJSON(userJSON: string): User {
const userObj = JSON.parse(userJSON);
const { firstname, lastname, email, password } = userObj;
const user = new User(firstname, lastname, email, password);
return user;
}
Depending on how your test framework compares object instances you should be able to check for equality something like this:
const user = new User("a", "b", "[email protected]", "1");
const decodedUser = decodeUserFromJSON(`{"firstname": "a", "lastname": "b", "email": "[email protected]", "password": "1" }`);
expect(decodedUser).toEqual(user);
Upvotes: 2