When you write a class declaration in TypeScript like
class Student {
name: string = ''
}
it brings into scopes two things named Student. One is the class constructor value that exists at runtime in JavaScript. It's an object named Student and you can write new Student() to construct a new class instance value. The other is the class instance type that exists only in TypeScript's type system. It's a type named Student and you can write let student: Student to tell TypeScript that the type of student is the instance type of the Student class. Even though they share a name and are related, they are not the same thing.
TypeScript doesn't get confused about which thing you're referring to because values and types live in different syntactic contexts in TypeScript. If you write x = new X(), that X is definitely a value, not a type. If you write let x: X;, that X is definitely a type, not a value. If you write interface Z extends X {}, that X is definitely a type, not a value.
See the TypeScript handbook documentation for more details.
It's also important to note that the class instance type behaves exactly like an interface. It's not declared using the interface keyword, but it behaves the same. Indeed, the Student declaration above is quite similar to the pair
interface Student {
name: string
}
const Student: new () => Student = class {
name: string = ""
};
where the two things named Student are defined explicitly and separately.
If we put those together, we can understand what
class Student {
name: string = ''
}
class Employee {
salary: number = 0
}
interface Work_Study extends Student, Employee {
description: string;
}
is doing. The interface declaration with the extends clause is just declaring a new interface which inherits from the Student and Employee types. It has nothing whatsoever to do with the Student and Employee constructors. It's exactly the same as
interface Student {
name: string
}
interface Employee {
salary: number;
}
interface Work_Study extends Student, Employee {
description: string;
}
And multiple inheritance of interfaces is unproblematic.
On the other hand, something like
class Work_Study extends Student, Employee {
description: string = "oops"
}
is different, in that it's a class declaration and involves the value space. It's invalid because that's the JavaScript extends clause which only allows extending a single parent class. Multiple inheritance in JavaScript classes is prohibited (to avoid the diamond problem where it's ambiguous which implementation to use).
While class Work_Study extends Student, Employee {} and interface Work_Study extends Student, Employee {} look similar, they are in completely different syntactic contexts, and behave differently. The former is illegal multiple class inheritance, while the latter is legal multiple interface inheritance.
Playground link to code
class,interface, ortype. The interface does not care (or know) about the definitions (implementations) of theclassmethods.Work_Study_Studentis neither a subclass ofStudentnor a subclass ofEmployee- it does not inherit their methods, andinstanceofwill return false. All it does is to declare that it is compatible with some types.class X {}introduces two things namedXinto scope. One is the JS class constructor valueXthat exists at runtime, and the other is the class instance interface typeXthat exists only in TS's type system. The latter is what you are referring to withinterface Y extends X {}. Thus you can freely extend multiple class instance types, since they are just interfaces. You are not touching the classes at runtime. Does that make it clear?declare class X {y: string; z: number}it behaves very much likeinterface X { y: string; z: number }; declare const X: new () => X;. A class declaration declares an interface-like type corresponding to the class instance type, and a const-like value corresponding to the constructor. The instance type isn't literally an interface, but it behaves almost exactly like one. And when you writeinterface W extends X {}thatXis the type, not the value. Does that make it clear? I'm happy to write an answer but I want to make sure it applies first.