We’ve already briefly looked at classes in TypeScript and classes in JavaScript, so let’s delve a little deeper now.
Since TypeScript is just JavaScript, with some added on bits, we can create a class as we normally would with the adding of types as you see below.
class Point {
x: number;
y: number;
// Normal constructor with default values
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
}
However, we can overload our constructors to see if there is anything different we might need:
constructor(x: number, y: number);
constructor(x: string | number, y: number = 0) {
// do logic stuff here...
}
Note: Notice how the function headers differ, but there is still only one body.
Calling super()
We can extend a class in TypeScript just like we can in JavaScript. We can likewise call super()
just like we can in Java, to call our parent classes constructor. This makes developing the code much easier, as it was already done, in some cases, for us. This means we’re less likely to forget to initialize a variable, less likely to have errors, and if we do, it should be easier to debug and fix them.
However, TypeScript will make sure we don’t call super after calling a property with the this.
keyword.
class Point3D extends Point {
z: number;
// overloaded constructor
constructor(x: number, y: number, z: number = 0) {
console.log(this.x); // this should be an error, and TypeScript will raise it
super(x,y);
}
}
This is the error you will get: super
must be called before accessing this
in the constructor of a derived class.
Working with Methods
We’ve already seen how types can be applied to function parameters and return types. The same can be done with methods of a class, so we don’t need to recover that.
However, we get the ability to easily have getters and setters in TypeScript.
One common method to “hide” properties in JavaScript like you would with a private accessor in other languages is to put an underscore before the variable name. This is similar to Python’s dunbar (double underscore). It doesn’t really hide it, it just makes it a little less obvious. Then we can use getters and setters.
class Point {
_x: number;
_y: number;
}
Here we see the properties. Now we just need to add a getter and setter.
////////////////
// these are both in the class point
////////////////
get x(): number {
return this._x;
}
set x(value:number) {
this._x = value;
}
Note: If get
exists but no set
, the property is automatically readonly
To call the getter and setter is a little different, though. We don’t use the parenthesis like we would for a normal function/method. This is also why we use the single underscore, so that we don’t have duplicate identifiers (names of functions and variables/methods and properties)
let p = new Point(4,5);
console.log( p.x );
Other OO Concepts
Interfaces
Just like in languages, JavaScript supports the Interface and implementation of Interfaces (think Java).
Overriding
It also allows you to override a method from a base (parent) class.
Visibility
In ES2020, JavaScript got the ability to have real accessors for methods and properties. However, TypeScript gives us a little more common method of doing it, especially if you are used to C++, Java, or other OOP languages.
While all methods and properties are public by default, we can use the private
and protected
keywords before the property or method name to make them private or protected. Which means our previous example becomes:
class Point {
private _x: number;
private _y: number;
get x(): number {
return this.x;
}
set x(value:number) {
this.x = value;
}
}
Notice we still have the underscores, so we don’t duplicate the identifier. But now we make sure that they are not accessible to other code.
Classes in TypeScript was originally found on Access 2 Learn