o7planning

TypeScript Methods Tutorial with Examples

  1. What is the method?
  2. Regular method
  3. Static method
  4. Abstract method
  5. Optional parameters
  6. Parameters with default values
  7. Parameters with union data type
  8. Override a method
  9. Method Overloading

1. What is the method?

In the TypeScript programming language, a method is a block of code, defined inside a class and only executed when being called. Methods divide a large task into small parts and perform the specific operation of that program. This process increases code reusability and enhances the program's modular approach.
Basically, methods are divided into 3 types:
  • Regular method (non-static and non-abstract).
  • Static method.
  • Abstract method.

2. Regular method

The syntax for defining a regular method:
[private | protected | public] method_name(arguments) : return_type {  
     // statement(s)  
}
  • return_type: The return data type of the method. Use the void keyword as a return type if the method returns nothing.
  • method_name: The method name. Unlike other languages like Java, TypeScript does not allow two methods with the same name, even if they have different parameters. This is necessary to be able to convert TypeScript code to Javascript.
  • arguments: The method's parameters.
Example: Cat class and its sayHello(..) method. To call sayHello(..) you must create a Cat object and call the method using dot notation.
method_ex1.ts
class Cat {
    sayHello(name: string): void {
        console.log(`Hello ${name}`);
    }
}
function method_ex1_test() {
    var tom: Cat = new Cat(); // Create a Cat object.
    tom.sayHello("Jerry"); // Call the method through the object.
}
// Call the method:
method_ex1_test();
Output:
Hello Jerry
A method can contain 0, 1, or more parameters, separated by commas.
method_ex2.ts
class Rectangle {
    width: number;
    height: number;

    constructor(width: number, height: number) {
        this.width = width;
        this.height = height;
    }
    getArea(): number {
        return this.width * this.height;
    }
    changeWidthHeight(newWidth: number, newHeight: number): void {
        this.width = newWidth;
        this.height = newHeight;
    }
    showMe(): void {
        console.log(`I am a rectangle, width: ${this.width}, height: ${this.height}`);
    }
}
function method_ex2_test() {
    var rec = new Rectangle(5, 10); // Create an object.

    rec.showMe();  // Call the method.
    var area = rec.getArea();  // Call the method.
    console.log(`Area: ${area}`);

    console.log(` --- Change width and height --- `);
    rec.changeWidthHeight(25, 15); // Set newWidth, newHeight

    rec.showMe(); // Call the method.  
    area = rec.getArea(); // Call the method.
    console.log(`Area: ${area}`);
}
method_ex2_test(); // Call the function.
Output:
I am a rectangle, width: 5, height: 10
Area: 50
 --- Change width and height ---
I am a rectangle, width: 25, height: 15
Area: 375

3. Static method

TypeScript uses the static keyword in conjunction with the regular method definition syntax to define a static method.
Syntax:
[private | protected | public] static method_name(arguments) : return_type {  
     // statement(s)  
}
Characteristics of static methods:
  • The static method is called via the class name and dot notation. For example MyUtility.sum(100, 50).
  • Non-static members of a class cannot appear in a static method unless they are accessed through the object (See the example below).
method_static_ex1.ts
class MyUtility {
    static sum(a: number, b: number): number { // same as 'public'
        return a + b;
    }
    public static minus(a: number, b: number): number {
        return a - b;
    }
}
function method_static_ex1_test() {
    var result = MyUtility.sum(100, 50);
    console.log(`Sum Result: ${result}`);

    result = MyUtility.minus(100, 50);
    console.log(`Minus Result: ${result}`);
}
method_static_ex1_test(); // Call the method
Output:
Sum Result: 150
Minus Result: 50
Next, look at the example below:
  • side1, side2 and side3 are non-static fields of the Triangle class, they cannot appear in static method.
method_static_ex2.ts
class Triangle {
    side1: number; side2: number; side3: number;// Non-static fields (Cann't use in static method)
    static DEFAULT_COLOR:string = 'blue'; // Static field (Can use in static method)

    constructor(s1: number, s2: number, s3: number) {
        var valid = Triangle.isValidSides(s1, s2, s3); // Check if all sides are valid.
        if (!valid) {
            throw new Error('Invalid Sides!'); // Throw an Error.
        }
        this.side1 = s1;
        this.side2 = s2;
        this.side3 = s3;
    }
    static isValidSides(s1: number, s2: number, s3: number): boolean {
        if (s1 < 0 || s2 < 0 || s3 < 0) {
            return false;
        }
        return s1 + s2 > s3 && s1 + s3 > s2 && s2 + s3 > s1;
    }
    isEquilateralTriangle(): boolean {
        return this.side1 == this.side2 && this.side2 == this.side3;
    }
}
function method_static_ex2_test() {
    var valid = Triangle.isValidSides(6, 8, 10);
    console.log(`Are sides 6, 8 and 10 valid to make a triangle? ${valid}`);

    var triangle = new Triangle(3.0, 4.0, 5.0);
    // Check if the triangle is equilateral triangle.
    var check = triangle.isEquilateralTriangle();
    console.log(`Is Equilateral Triangle? ${check}`);
}
method_static_ex2_test(); // Call the method.
Output:
Are sides 6, 8 and 10 valid to make a triangle? true
Is Equilateral Triangle? false

4. Abstract method

In the TypeScript language, an abstract method is a non-static method and has no content.
[protected | public] abstract method_name(arguments) : return_type;
A class with at least one abstract method must be declared abstract, and one of its subclasses must override these abstract methods and write content for them.
method_abstract_ex1.ts
abstract class Person {
    abstract sayHello(): void; // An abstract method.
}
class EnglishPerson extends Person {
    sayHello(): void {
        console.log("Hello");
    }
}
class RussianPerson extends Person {
    sayHello(): void {
        console.log("Привет");
    }
}
function method_abstract_ex1_test() {
    var enPerson = new EnglishPerson();
    enPerson.sayHello();

    var ruPerson = new RussianPerson();
    ruPerson.sayHello();
}
method_abstract_ex1_test(); // Call the function.
Output:
Hello
Привет
  • TypeScript Classes

5. Optional parameters

As mentioned above, classes in TypeScript and JavaScript do not allow methods with the same name, but a method can include optional parameters.
Syntax:
// Non-static method with optional arguments:
[private | protected | public] method_name(args, optional_args?): return_type {  
     // statement(s)  
}

// Static method with optional arguments:
[private | protected | public] static method_name(args, optional_args?) : return_type {  
     // statement(s)  
}

// Abstract method with optional arguments:
[protected | public] abstract method_name(args, optional_args?): return_type;
Example:
method_optional_args_ex1.js
class MyUtils {
    static concat(s1: string, s2: string, s3?: string): string {
        if (s3) {
            return s1 + s2 + s3;
        }
        return s1 + s2;
    }
    static sum(v1: number, v2: number, v3?: number, v4?: number): number {
        return v1 + v2 + (v3 ?? 0) + (v4 ?? 0);
    }
}
function method_optional_args_ex1_test() {
    var result1 = MyUtils.concat('One', 'Two');
    console.log(`result1: ${result1}`);

    var result2 = MyUtils.concat('One', 'Two', 'Three');
    console.log(`result2: ${result2}`);

    var value1 = MyUtils.sum(1, 2, 3, 4);
    console.log(`value1: ${value1}`);

    var value2 = MyUtils.sum(1, 2, 3);
    console.log(`value2: ${value2}`);

    var value3 = MyUtils.sum(1, 2);
    console.log(`value3: ${value3}`);
}
method_optional_args_ex1_test(); // Call the method.
Output:
result1: OneTwo
result2: OneTwoThree
value1: 10
value2: 6
value3: 3

6. Parameters with default values

TypeScript supports methods with default-valued parameters, which must be the last parameters in the list of parameters.
Syntax:
// Non-static method
[private | protected | public ] method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type {
    // statement(s)  
}
// Static method
[private | protected | public ] static method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type {
   // statement(s)  
}
// Abstract method
[protected | public ] abstract method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type3 = defaultValue3,
             arg4 : data_type4 = defaultValue4) : return_type;
Example:
method_default_value_args_ex1.ts
class SalesUtils {
    static applyDiscount(amount : number, discount: number = 0.05)  : number {
        return amount * (1 - discount);
    }
}
function method_default_value_args_ex1_test() {
    var value1 = SalesUtils.applyDiscount(1000);
    console.log(`value1 = ${value1}`);

    var value2 = SalesUtils.applyDiscount(1000, 0.5);
    console.log(`value2 = ${value2}`);
}
method_default_value_args_ex1_test(); // Call the method.
Output:
value1 = 950
value2 = 500

7. Parameters with union data type

The parameter in a method can also be declared with a union data type.
// Non-static method
[private | protected | public ] method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4 = defaultValue4) : return_type {
    //  Statament(s)
}
// Static method
[private | protected | public ] static method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4) : return_type {
    //  Statament(s)  
}
// Abstract method
[protected | public ] abstract method_name (
             arg1 : data_type1, arg2 : data_type2,
             arg3 : data_type31 | data_type32 | data_type3N, // Union Data Type
             arg4 : data_type4) : return_type;
Example:
method_union_type_args_ex1.ts
interface IStudent {
    studentId: number,
    studentName: string
}
interface IWorker {
    workerId: number,
    workerName: string
}
class AppUtils {
    static getName(person: IStudent | IWorker): string { // Union Type Arg
        var p = person as IStudent;
        if (p.studentName) {
            return p.studentName;
        }
        return (person as IWorker).workerName;
    }
}
function method_union_type_args_ex1_test() {
    var student = { studentId: 1, studentName: "Tom" };
    var worker = { workerId: 2, workerName: "Jerry" };

    var name1 = AppUtils.getName(student);
    var name2 = AppUtils.getName(worker);
    console.log(`name1: ${name1}`);
    console.log(`name2: ${name2}`);
}
method_union_type_args_ex1_test(); // Call the method.
Output:
name1: Tom
name2: Jerry

8. Override a method

A subclass can override a method of the parent class if the following conditions are met:
  • The two methods must have the same name and the same parameters.
  • The return type of the two methods must be the same, or the return type of the method in the subclass must be a subtype of the return type of the method in the parent class.
Example:
  • The Mouse class overrides the sayAnything() method of the Animal class.
method_override_ex1.ts
class Animal {
    sayAnything(): void {
        console.log('<Nothing>');
    }
}
class Mouse extends Animal {
    sayAnything(): void { // Override method of parent class.
        console.log('Hi Tom!');
    }
}
function method_override_ex1_test() {
    var animal = new Mouse();
    animal.sayAnything(); // Hi Tom!
}
method_override_ex1_test(); // Call the function.
Output:
Hi Tom!
Example: You can also use the super keyword to call a method with the same name of the parent class.
method_override_ex2.ts
class BoldFormatter {
    formatText(text: string): string {
        return '<b>' + text + '</b>';
    }
}
class BoldItalicFormatter extends BoldFormatter {
    formatText(text: string): string { // Override method of parent class.
        var boldText = super.formatText(text); // Call super method.
        return '<i>' + boldText + '</i>';
    }
}
function method_override_ex2_test() {
    var formatter = new BoldItalicFormatter();
    var formattedText = formatter.formatText('Hello');
    console.log(formattedText);
}
method_override_ex2_test(); // Call the method.
Output:
<i><b>Hello</b></i>

9. Method Overloading

In the article about functions in TypeScript, I introduced "Function Overloading". The method is considered as a function of the class, so it also has a similar concept, which is "Method Overloading".
TypeScript does not allow two methods with the same name in a class even if they have different parameters. Method Overloading allows you to define a method with different parameters types.
In TypeScript, Method Overloading looks different from C++, Java, or C#. The main idea for method overloading is to create a generic method that checks what type of parameter was passed when the method was called, and then do some logic for the appropriate case. It is useful to add definitions for the method to help other programmers know how to use it appropriately.
Syntax:
// Definition 1
[static] method_name(arg_11 : type_11, arg_1N : type_1N): return_type;
]// Definition 2
[static] method_name(arg_21 : type_21, arg_22 : type_22, arg_2M : type_2M) : return_type;
[static] method_name(... args : any[]) : return_type {
   // Method body.
}
Example:
method_overloading_ex1.ts
interface IDimension {
    width: number,
    height: number
}
class MathUtils {
    static getArea(dimension: IDimension): number; // Definition 1
    static getArea(width: number): number; // Definition 2
    static getArea(width: number, height: number): number; // Definition 3
    static getArea(...args: any[]): number {
        if (args.length == 1) {
            if (typeof args[0] == 'number') { // Use Definition 2
                return args[0] * args[0];
            } else { // Use Definition 1
                var dim = args[0] as IDimension;
                return dim.width * dim.height;
            }
        } else if (args.length == 2) {
            return args[0] * args[1];
        } else {
            throw new Error('Arguments Invalid!');
        }
    }
}
function method_overloading_ex1_test() {
    var area1 = MathUtils.getArea({ width: 10, height: 20 }); // 200
    var area2 = MathUtils.getArea(10); // 100
    var area3 = MathUtils.getArea(10, 15); // 150

    console.log(`area1: ${area1}`);
    console.log(`area2: ${area2}`);
    console.log(`area3: ${area3}`);
}
method_overloading_ex1_test(); // Call the function.
Output:
area1: 200
area2: 100
area3: 150