Typecasting (like you're doing) isn't going to change the type of the object. What you're actually doing is this:
obj1 = [MyType initWithData: 1];
"I just created a object of type MyType, now point obj1 at it. Since obj1 is a MyType pointer, it's okay."
If you were to the next line without the typecast:
obj2 = obj1;
You're saying, "point obj2 at the same thing obj1 is pointing to", which will work but the compiler know obj1 is a MyType pointer and obj2 is a MyOtherType pointer so it throws a warning telling you they are incompatible.
So when you say:
obj2 = (MyOtherType*) obj1;
All you're saying is, "point obj2 at the same thing obj1 is pointing to, OH and treat obj1 as if it were an MyOtherType object". This is cool with the compiler since as far as it is concerned it's just assigning a MyOtherType to a MyOtherType. But this doesn't actually change the object that obj1 is pointing to. So when you pass the 'isMemberOfClass' message to obj1, it's still going to be and report that it is a member of MyType.
One solution to your problem would be to write your own custom initializer or converter (something like this):
- (id)initWithMyType:(MyType*)originalType;
And then do the conversion in there