Yeah don't do that. :)
Do this:
interface Dog { typeName: "Dog"; woof():void }
interface Cat { typeName: "Cat"; meow():void }
function isDog(a:Dog|Cat) : a is Dog {
return a.typeName == "Dog"; // Some casting may be required here
}
function f(a: Dog|Cat) {
if (isDog(a)) a.woof();
else a.meow();
}
let dogish : Dog = {typeName:"Dog", woof: ()=>{ console.out("Woof this is Dog")}};
f(dogish);
The neat thing about TypeScript's type system is that it's structural but you can pretty easily implement nominal types on top of it.(And if you only need compile-time checks, you can make typeName nullable; {typeName?:"Dog"} != {typeName?:"Cat"})