class Animal { name: string; constructor(name: string) { this.name = name; } } class Dog extends Animal { breed: string; constructor(name: string, breed: string) { super(name); this.breed = breed; } } let animal: Animal = new Dog('Buddy', 'Golden Retriever'); console.log(animal.name);
The variable animal is typed as Animal but holds an instance of Dog. Since Dog extends Animal, it has the name property. So, animal.name outputs "Buddy".
class Car { wheels: number = 4; } class Boat { sails: number = 2; } let vehicle: Car = new Boat();
TypeScript checks structural compatibility. Boat does not have the wheels property required by Car. So, the assignment causes a type error.
class Person { private id: number; constructor(id: number) { this.id = id; } } class Employee { private id: number; constructor(id: number) { this.id = id; } } let p: Person = new Employee(123);
In TypeScript, classes with private or protected members are only compatible if they originate from the same declaration. Here, Person and Employee have private id members declared separately, so they are incompatible.
class Alpha { x: number = 1; } class Beta extends Alpha { y: number = 2; } class Gamma { y: number = 2; } let a: Alpha; let b: Beta; let g: Gamma;
Since Beta extends Alpha, an instance of Beta can be assigned to a variable of type Alpha. The reverse is not true. Gamma is unrelated structurally to Alpha and Beta.
class Base { greet(): string { return "Hello from Base"; } } class Derived { greet(): string { return "Hello from Derived"; } } let base: Base = new Derived(); console.log(base.greet());
TypeScript uses structural typing. Derived has the same method greet as Base. So, Derived is compatible with Base. At runtime, the greet method of Derived is called, printing "Hello from Derived".