An abstract class supplies shared behavior but is never instantiated directly. JavaScript has no abstract keyword, but new.target holds the class new was called on, so the base constructor can refuse direct use and check for required methods. TypeScript's abstract (Classes) checks this at compile time.
class Shape {
constructor() {
if (new.target === Shape) throw new TypeError('Shape is abstract');
if (!this.area) throw new TypeError(`${new.target.name} must implement area()`);
}
describe() { return `${this.constructor.name}: ${this.area().toFixed(2)}`; } // template
}
class Circle extends Shape { area() { return Math.PI; } }
class Blob extends Shape {} // forgot area()
console.log(new Circle().describe());
for (const C of [Shape, Blob]) try { new C(); } catch (e) { console.log(e.message); }Circle: 3.14 Shape is abstract Blob must implement area()