CodePark/ questions / Abstract classes, interfaces & structural typing
START PRACTICINGPRACTICE
Backend question · Object-oriented programming › Abstract classes, interfaces & structural typing

You need a PaymentGateway contract with Stripe and PayPal versions. Would you use an interface, an abstract class or a type alias? Explain the trade-offs.

It depends on whether you need code or a runtime value. Usually an interface is enough.

Interface (or type alias):

  • Describes only the shape: charge(amount: Money): Promise<ChargeId>.
  • It is erased when TypeScript compiles. Nothing exists at runtime.
  • A class can implement many interfaces.
  • Best for a pure contract. For an object shape, an interface and a type alias behave almost the same.

Abstract class:

  • Can hold shared code: retries, logging, a template method that calls abstract doCharge().
  • It is a real JavaScript class at runtime. So instanceof works, and NestJS can use it as an injection token without @Inject.
  • A class can extend only one abstract class. So it ties each implementation to that base.

How I choose:

  • Interface for the contract.
  • Abstract class when the implementations really share logic, or when I want a runtime token in NestJS.
  • Composition (inject a RetryPolicy) instead of a base class when the shared code is only a helper.
  • An interface is a compile-time shape and is erased at runtime.
  • An abstract class exists at runtime and can contain shared code.
  • A class can implement many interfaces but extend only one class.
  • An abstract class can be a NestJS injection token, but an interface cannot.
  • Prefer an interface, and use an abstract class only when there is real shared code or you need a runtime token.