Lesson 21 of 80
A class you can't instantiate directly, meant to be extended — plus private/protected/public, the access control JavaScript classes never had until TypeScript (and later, real JS private fields) added it.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
Can you write `new Shape()` if Shape is declared as `abstract class Shape { ... }`?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
abstract class Shape {
abstract area(): number; // no body — subclasses must provide one
describe(): string {
return `Area: ${this.area()}`; // concrete method, shared by every subclass
}
}
class Circle extends Shape {
constructor(private radius: number) { super(); }
area(): number { return Math.PI * this.radius ** 2; }
}
new Shape(); // ❌ cannot create an instance of an abstract class
new Circle(3); // ✅
abstract marks both the class itself (can't be new'd directly) and specific methods (no implementation, just a signature subclasses are required to fill in) — while describe(), a normal concrete method, is inherited and shared as-is. This is the prototype chain (from the JavaScript track) with the compiler enforcing a contract on top of it: every subclass genuinely has an area().
class Account {
private balance: number = 0; // only accessible inside this class
protected id: string = "acc_1"; // accessible in this class and subclasses
public owner: string = "Ada"; // accessible from anywhere (the default)
}
abstract class Shape { abstract area(): number; } — no body here; it's a contract, not code.
private in TypeScript is erased at compile time — nothing stops plain JavaScript (or a type assertion) from reading account["balance"] at runtime; only #balance (real private fields) is enforced by the JS engine itself.private constructor() is a real, useful pattern for enforcing "only create instances of this class through a specific static factory method," a common building block for the singleton pattern.interface cannot."What's the difference between TypeScript's private and JavaScript's #private fields?" is a precise, current question — the honest answer (compile-time-only vs. runtime-enforced) shows you understand where TypeScript's guarantees actually stop.