TypeScript is the jacked-up version of JavaScript💪. It's JavaScript on steroids with the same syntax and the added requirement for type annotation. For example, the following variable is declared differently in TypeScript than in JavaScript.
JavaScript:
let name = 'Tawanda'
TypeScript:
let name: string = 'Tawanda'
This annotation adds type safety, reducing errors caused by incompatible type conversion. The code snippet below is valid JavaScript but not TypeScript.
let name = 'Tawanda';
name = 50
This article explores how classes are written in TypeScript. If you already know how to write them in JavaScript, then this will be a fairly simple concept to understand. Below is an example of a class written in TypeScript.
class Car {
name: string
model: string
mileage: number
color: string
constructor (name: string, model: string, mileage: number, color: string) {
this.name = name
this.model = model
this.mileage = mileage
this.color = color
}
}
In JavaScript, there is no need to define the data types at the beginning i.e. name: string
. Also, you will get an error in TypeScript if you do not define the initializer inside the constructor e.g. this.model = model
. The code snippet above is a safe template for writing a class in TypeScript. We can also add visibility modifiers to avoid redundancy.
Visibility Modifiers
Also called access modifiers, are prefixes given to variables inside a class that specify their access level. We can rewrite the code above as shown below:
class Car {
constructor (
public name: string,
public model: string,
public mileage: number,
public color: string
) {
this.name = name
this.model = model
this.mileage = mileage
this.color = color
}
}
const Benz = new Car('Mercedes', 'AMG-GT', 5000, 'yellow')
console.log(Benz)
By default, all variables inside a TypeScript class are public. The simple table below explains all the visibility modifiers.
Name | Description | Syntax |
---|---|---|
Public | A value that can be changed. | public |
Private | A value which can only be accessed inside the class. | private |
Protected | A value which can be accessed inside the class and its subclasses. | protected |
Read Only | A value which cannot be changed. | readonly |
Static | A 'static' modifier cannot be a parameter of the constructor. The static keyword applies the variable to the class and not to any of its instantiation. | static |
Based on this information, we can rewrite our class definition as shown below:
class Car {
constructor (
readonly name: string,
public model: string,
private mileage: number,
public color: string,
protected engine: string = 'V8',
) {
this.name = name
this.model = model
this.mileage = mileage
this.engine = engine
this.color = color
}
public getMileage () {
return `The mileage for the ${this.name} ${this.model} is ${this.mileage}`
}
}
const Benz = new Car('Mercedes', 'AMG-GT', 5000, 'Combustion')
console.log(Benz)
Notice how the color value is now optional since it has been changed to a protected value. If we try to output the two values as shown below, we get an error for the second console log statement.
console.log(Benz.getMileage()) // The mileage for the Mercedes AMG-GT is 5000.
console.log(Benz.mileage) // Property 'mileage' is private and only accessible within class 'Car'.
console.log(Benz.name) // Mercedes.
console.log(Benz.color) // Property 'color' is protected and only accessible within class 'Car' and its subclasses.
The example below shows a derived class or subclass of Car.
class ElectricCar extends Car {
constructor (
public battery: string,
name: string,
model: string,
mileage: number,
color: string,
engine: string
) {
super(name, model, mileage, color, engine)
this.battery = battery
}
public getBatteryDetails(){
return `The electric car is a ${this.name} and it uses a ${this.battery} battery.`
}
}
const Tesla = new ElectricCar('Lithium', 'Tesla', 'Model X', 5000, 'Red', 'None')
console.log(Tesla.getBatteryDetails())
console.log(Tesla.name) // Tesla
console.log(Tesla.model) // Model X
console.log(Tesla.mileage) // Property 'mileage' is private and only accessible within class 'Car'.
console.log(Tesla.color) // Red
console.log(Tesla.engine) // Property 'engine' is protected and only accessible within class 'Car' and its subclasses.
We use the super keyword to specify which properties of the Car class we want to access. Since the engine property from the Car class is protected, we cannot use it in the Electric Car class. The visibility of each value does not change because it is a derived class so the mileage class will remain private to the Car class.
Conclusion
These are the basics of writing classes in TypeScript. Everything else including more advanced concepts builds on top of what has been covered in this article. It is important to remember the different access modifiers (public, private, readonly, and protected). Classes can be a good way to write reusable modularized code allowing for better maintenance, readability, and testing. I've found myself using TypeScript more often in my projects because of the security that it brings. Thanks for reading and I hope you enjoyed this article. Until next time, happy coding!