All right, I found that TS has discriminated unions for such cases.
Just extend your interfaces with a common property and use it to narrow types in your code.
interfaceCat{kind:'cat';numberOfLives:number;}interfaceDog{kind:'dog';isAGoodBoy:boolean;}functionisCat(animal:Cat|Dog):animalisCat{returnanimal.kind==='cat';}functiongetAnimal():Cat|Dog{return{kind:'cat',numberOfLives:7}}letanimal=getAnimal();animal.numberOfLives// Error. Property 'numberOfLives' does not exist on type 'Cat | Dog'if(isCat(animal)){animal.numberOfLives// OK}
All right, I found that TS has discriminated unions for such cases.
Just extend your interfaces with a common property and use it to narrow types in your code.
I use the "as" keyword and then a specific property on the type.
so in your above example you could leave out the "kind" property:
I like not having to add the extra property to my types. :)
Full code for my example found in this file: github.com/mirkoRainer/RulesLawyer...