November 10, 2022 • 1 min read
I learned you can create class instances pretty easily with class expressions. As you might have already learned from my other post on self invoking function expressions, in JavaScript you can utilize function expressions to immediately run some code or preserve state. You can do the same with class expressions.
In the following snippet we implement the CarAPI
using a class expression.
1interface CarAPI {2start(): Promise<void>3stop(): Promise<void>4getSpeed(): number5}
To create our class instance we just do:
1const car = new (class implements CarAPI {2start() {3return Promise.resolve()4}5stop() {6return Promise.resolve()7}8getSpeed() {9return 3010}11})
To use our car
we can call an API method from the car
instance like we do with normal class instantiations.
1// 30;2console.log(car.getSpeed());
You can also use the extend
keyword to create a new class instance that extends from a base class.
1const superCar = new (class extends Car {2getSpeed() {3return 3004}5});67// 3008console.log(superCar.getSpeed());9superCar.start().then(() => {10console.log('Car started...')11})
Since it is an expression we can also opt to evaluate it inline.
1const superCarSpeed = new (class extends Car {2getSpeed() {3return 3004}5})().getSpeed();67// 3008console.log(superCarSpeed)
I have found that class expressions are useful when I need to quickly implement mock implementations of real class instances for unit tests. They also allow you to easily overwrite class API methods for providing different implementaions of the same API. This can also be done with the Object syntax implementation. For example I can implement the CarAPI like this as well:
1const objectCar: CarAPI = {2start() {3return Promise.resolve()4},5stop() {6return Promise.resolve()7},8getSpeed: () => 309}
This syntax makes it easy to extend and overwrite implementations as well. However, it does not allow for usage of
class specific constructs in your code like instanceOf
. As a result, if you were providing mock implementations of CarAPI
in your test and used instanceOf
internally to check what kind of Car you have, this will break your test. When I faced this
similar problem with some code I was working on, utilizing class expressions helped fix the misalignement between
test and product code giving me a clean test pass 😁