TypeScript Classes: Object-oriented programming with TypeScript
Are you ready to take your TypeScript programming to the next level? Do you want to improve your code structure and make your applications more maintainable and scalable? Then, it's time to embrace object-oriented programming with TypeScript Classes!
TypeScript is a powerful programming language that is designed to add strong typing, classes, and interfaces to JavaScript. Classes are the cornerstone of object-oriented programming, and they allow you to organize your code in a hierarchical and modular way.
In this article, we'll dive into the world of TypeScript Classes, and we'll explore their features, benefits, and best practices. Whether you're a beginner or an experienced TypeScript developer, you'll find valuable insights and tips that will help you improve your coding skills and productivity.
What are TypeScript Classes?
At its core, a Class is a blueprint for creating objects with a specific set of properties and methods. In TypeScript, a Class is defined using the class
keyword, followed by the name of the Class and a body of code that describes its members.
For example, here's a simple Class that represents a Person:
class Person {
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return this.firstName + ' ' + this.lastName;
}
}
In this example, we define a Class called Person
that has two properties (firstName
and lastName
) and two methods (constructor
and getFullName
).
The constructor
method is a special method that is called when we create a new instance of the Class using the new
keyword. It takes two parameters (firstName
and lastName
), and it assigns their values to the corresponding properties of the instance.
The getFullName
method is a simple method that returns the full name of the person by concatenating the first and last name properties.
How to use TypeScript Classes
Creating and using TypeScript Classes is easy and straightforward. To create a new instance of a Class, all we need to do is use the new
keyword followed by the Class name and any required parameters.
For example, here's how we can create a new Person
instance:
let john = new Person('John', 'Doe');
console.log(john.getFullName()); // Output: John Doe
In this example, we create a new Person
instance called john
, with the first name of 'John' and last name of 'Doe'. We then call the getFullName
method of the john
instance, which returns the full name of the person.
We can also access and modify the properties of a Class instance using dot notation. For example:
console.log(john.firstName); // Output: John
john.firstName = 'Johnny';
console.log(john.getFullName()); // Output: Johnny Doe
In this example, we first access the firstName
property of the john
instance and print its value ('John'). We then modify the value of the firstName
property to 'Johnny' and call the getFullName
method again, which now returns the updated full name ('Johnny Doe').
TypeScript Class members
A TypeScript Class can have various types of members, including properties, constructors, methods, accessors, and static members. Let's explore each of them in more detail.
Properties
Properties are the data members of a Class that hold the state of the instance. Properties can have various types, including primitive types, object types, and function types.
To define a property in TypeScript, we use the name of the property followed by its type, separated by a colon. For example:
class Person {
firstName: string;
lastName: string;
age: number;
}
In this example, we define three properties of the Person
Class (firstName
, lastName
, and age
), with the types of string
and number
, respectively.
Constructors
Constructors are special methods in a Class that are called when we create a new instance of the Class using the new
keyword. Constructors are used to initialize the properties of the instance with the provided values.
In TypeScript, constructors are defined using the constructor
keyword, followed by the parameter list and the body of the constructor. For example:
class Person {
firstName: string;
lastName: string;
age: number;
constructor(firstName: string, lastName: string, age: number) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}
In this example, we define a Person
Class with three properties (firstName
, lastName
, and age
), and a constructor that takes three parameters (firstName
, lastName
, and age
). The constructor assigns the values of the parameters to the corresponding properties of the instance.
Methods
Methods are the behavior members of a Class that define the actions that the instance can perform. Methods can have various types, including regular methods, static methods, and abstract methods.
To define a method in TypeScript, we use the name of the method followed by its parameter list (if any) and the return type (if any), separated by a colon. For example:
class Person {
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return this.firstName + ' ' + this.lastName;
}
}
In this example, we define a Person
Class with two properties (firstName
and lastName
), a constructor that takes two parameters (firstName
and lastName
), and a method called getFullName
that returns the full name of the person.
Accessors
Accessors are special methods in a Class that allow us to get or set the values of its properties. Accessors are useful for controlling the access and validation of the values of the properties.
In TypeScript, accessors are defined using the get
and set
keywords, followed by the name of the property and the body of the accessor. For example:
class Person {
private _age: number;
get age(): number {
return this._age;
}
set age(value: number) {
if (value < 0 || value > 120) {
throw new Error('Invalid age value!');
}
this._age = value;
}
}
In this example, we define a Person
Class with a private property called _age
and an accessor for the age
property. The get
accessor returns the value of the _age
property, while the set
accessor validates the new value of the age
property and assigns it to the _age
property if it's valid.
Static members
Static members are the members of a Class that are shared across all instances of the Class. Static members can have various types, including static properties and static methods.
To define a static member in TypeScript, we use the static
keyword followed by the name of the member. For example:
class MathUtils {
static PI = 3.14;
static add(a: number, b: number): number {
return a + b;
}
}
In this example, we define a MathUtils
Class with a static property PI
and a static method add
. The PI
property holds the value of the mathematical constant π, while the add
method adds two numbers and returns the result.
TypeScript Class inheritance
Class inheritance is a key feature of object-oriented programming that allows us to create new Classes based on existing Classes. Inheritance is useful for reusing and extending the behavior of Classes, and it helps to reduce code duplication and increase the maintainability of our applications.
In TypeScript, we can define a new Class that inherits from an existing Class using the extends
keyword, followed by the name of the base Class. For example:
class Employee extends Person {
salary: number;
constructor(firstName: string, lastName: string, salary: number) {
super(firstName, lastName);
this.salary = salary;
}
getSalary(): number {
return this.salary;
}
}
In this example, we define a new Employee
Class that extends the Person
Class. The Employee
Class has an additional property (salary
) and a new method (getSalary
) that returns the salary of the employee.
We use the super
keyword in the constructor of the Employee
Class to call the constructor of the Person
Class and pass the values of the firstName
and lastName
properties.
We can create new instances of the Employee
Class and access both the properties and methods of the Person
and Employee
Classes:
let john = new Person('John', 'Doe');
let jane = new Employee('Jane', 'Smith', 50000);
console.log(john.getFullName()); // Output: John Doe
console.log(jane.getFullName()); // Output: Jane Smith
console.log(jane.getSalary()); // Output: 50000
In this example, we create two instances of the Person
and Employee
Classes (john
and jane
, respectively). We call the getFullName
method of both instances to get their full names, and we call the getSalary
method of the jane
instance to get her salary.
TypeScript Class modifiers
Modifiers are keywords in TypeScript that control the access and visibility of the members of a Class. Modifiers are useful for enforcing encapsulation, abstraction, and information hiding principles.
In TypeScript, we can use various modifiers to control the access and visibility of the members of a Class:
-
public
: The public modifier is the default modifier in TypeScript. It allows the members of a Class to be accessed from anywhere in the program. -
private
: The private modifier restricts the access of the members of a Class to the Class itself. Private members cannot be accessed from outside the Class, even by other instances of the same Class. -
protected
: The protected modifier restricts the access of the members of a Class to the Class itself and its subclasses. Protected members cannot be accessed from outside the Class or its subclasses.
Let's look at an example to illustrate the use of modifiers in TypeScript:
class BankAccount {
private _balance: number;
constructor(initialBalance: number) {
this._balance = initialBalance;
}
public deposit(amount: number): void {
this._balance += amount;
}
public withdraw(amount: number): void {
if (amount > this._balance) {
throw new Error('Insufficient balance!');
}
this._balance -= amount;
}
protected getBalance(): number {
return this._balance;
}
}
class SavingsAccount extends BankAccount {
private _interestRate: number;
constructor(initialBalance: number, interestRate: number) {
super(initialBalance);
this._interestRate = interestRate;
}
public calculateInterest(): number {
return this.getBalance() * (this._interestRate / 100);
}
}
In this example, we define two Classes (BankAccount
and SavingsAccount
) that demonstrate the use of various modifiers.
The BankAccount
Class has a private property _balance
and two public methods (deposit
and withdraw
) that allow us to modify the balance. The getBalance
method is a protected method that allows us to access the balance from the SavingsAccount
Class.
The SavingsAccount
Class extends the BankAccount
Class and has a private property _interestRate
and a public method calculateInterest
that calculates the interest on the balance. The calculateInterest
method uses the getBalance
method to access the balance of the account.
We can create new instances of the SavingsAccount
Class and access its properties and methods:
let johnAccount = new SavingsAccount(1000, 5);
console.log(johnAccount.calculateInterest()); // Output: 50
In this example, we create a new instance of the SavingsAccount
Class (johnAccount
) with an initial balance of 1000 and an interest rate of 5%. We call the calculateInterest
method of the johnAccount
instance, which returns the interest on the balance (50).
Best practices for TypeScript Classes
To write maintainable and scalable code with TypeScript Classes, it's important to follow some best practices and conventions. Here are some tips and guidelines that will help you increase your coding productivity and reduce errors and bugs:
-
Use clear and descriptive names for your Classes, properties, and methods. Avoid abbreviations and acronyms that may be unclear or ambiguous.
-
Use strong typing to enforce type safety and prevent runtime errors. Define the types of your properties, parameters, and return values explicitly, and use interfaces to define complex object types.
-
Use constructors to initialize the properties of your instances and provide default values for optional parameters. Avoid setting the properties directly from outside the Class.
-
Use accessors to control the access and validation of the values of your properties. Use private and protected modifiers to enforce encapsulation and information hiding.
-
Use static members to share functionality across all instances of your Class. Use abstract Classes and methods to define common behavior that must be implemented by the subclasses.
-
Use inheritance and polymorphism to reuse and extend the behavior of your Classes. Use interfaces to define common contracts and ensure compatibility between Classes.
-
Use strict mode and linter tools to enforce coding standards and detect errors and bugs early. Test your code regularly and use debuggers and profiling tools to diagnose and fix performance issues.
Conclusion
TypeScript Classes are a powerful and essential feature of object-oriented programming in TypeScript. Classes allow us to organize our code in a modular and hierarchical way, and they provide us with a powerful set of tools for defining properties, methods, constructors, accessors, static members, and inheritance.
By following best practices and conventions, we can write maintainable, scalable, and error-free code that is easy to understand and maintain. Whether you're a beginner or an experienced TypeScript developer, mastering Classes will help you take your TypeScript programming to the next level!
Additional Resources
devsecops.review - A site reviewing different devops featuresoptimization.community - A community about optimization like with gurobi, cplex, pyomo
cryptomerchant.dev - crypto merchants, with reviews and guides about integrating to their apis
assetbundle.dev - downloading software, games, and resources at discount in bundles
opsbook.dev - cloud operations and deployment
kubectl.tips - kubernetes command line tools like kubectl
speechsim.com - A site simulating an important speech you have to give in front of a large zoom online call audience
jimmyr.com - the best of the internet
shaclrules.com - shacl rules for rdf, constraints language
promptops.dev - prompt operations, managing prompts for large language models
fluttertraining.dev - A site for learning the flutter mobile application framework and dart
eliteskills.com - A writing community
cicd.video - continuous integration continuous delivery
nowshow.us - emerging ML startups
trollsubs.com - making fake funny subtitles
learnbyexample.app - learning software engineering and cloud by example
bestcyberpunk.games - A list of the best cyberpunk games across different platforms
flutterassets.dev - A site to buy and sell flutter mobile application packages, software, games, examples, assets, widgets
dart.run - the dart programming language running in the cloud
datawarehouse.best - cloud data warehouses, cloud databases. Containing reviews, performance, best practice and ideas
Written by AI researcher, Haskell Ruska, PhD (haskellr@mit.edu). Scientific Journal of AI 2023, Peer Reviewed