Start learning free

LESSON 252 OF 573 · FUNCTIONS & CLASSES

Rectangle Class in TypeScript: Fields, Constructor and Methods

Practice O(1) Read the full explanation

A class bundles some values with the questions you can ask about them. Write a class Rectangle that remembers a rectangle's width and height, and can tell its area, its perimeter, and whether it is a square.

Implement the class Rectangle:

  • Rectangle(width, height) creates a rectangle with the given sizes.
  • area() returns the area of the rectangle: its width times its height.
  • perimeter() returns the perimeter: the length all the way around, twice the width plus twice the height.
  • isSquare() returns true if the width and the height are equal, and false otherwise.

Each line of the input is one rectangle: its width and its height. The test code first creates a Rectangle for every line, then asks each of them, in order, for its area, its perimeter and whether it is a square, and prints the three answers on one line, the boolean as True or False. So each object must keep its own sizes. The starter code spells these names the way your language does (in Go and Rust, Rectangle is a struct with methods).

 

Example 1:

Input:
    Rectangle(3, 4)
Output: 12 14 False
Explanation: The area is 3 · 4 = 12. Going around, the sides are 3 + 4 + 3 + 4 = 14.
The width and the height differ, so it isn't a square.

Example 2:

Input:
    Rectangle(5, 5)
Output: 25 20 True
Explanation: 5 · 5 = 25, and 4 sides of 5 make 20. Both sizes are 5: a square is a rectangle with equal sides.

Example 3:

Input:
    Rectangle(2, 10)
    Rectangle(10, 2)
Output:
20 24 False
20 24 False
Explanation: Two objects, each with its own sizes. Turning a rectangle on its side changes neither its area nor its perimeter.

 

Constraints:

  • 1 <= width, height <= 104
  • At most 10 rectangles per test.

Note:

Each method needs only the two sizes, so each one runs in O(1) time.

STEP 1 OF 5
    Ctrl + Enter to check

    TYPESCRIPT · FUNCTIONS & CLASSES

    Rectangle Class in TypeScript, explained

    Problem overview

    A class bundles values with the questions you can ask about them. Rectangle remembers a width and a height, and answers three questions: its area(), its perimeter(), and whether it isSquare(). Each object keeps its own sizes, so two rectangles never interfere with each other.

    For new Rectangle(3, 4) the area is 3 · 4 = 12, and walking around the sides gives 3 + 4 + 3 + 4 = 14. The sizes differ, so it is not a square. For new Rectangle(5, 5) the area is 25, the perimeter 20, and it is a square.

    Approach

    There is nothing to search or sort here. The class needs two pieces of state, width and height, and each method is a one-line formula over them. Every method runs in constant time because it only reads two numbers.

    Step by step

    1. Declare the fields. Inside the class body, width: number; and height: number; say that every Rectangle object carries these two values.
    2. Fill them in the constructor. The parameters have the same names as the fields, so this.width = width; reads as "the field of this object gets the parameter".
    3. Area. Multiply the two fields.
    4. Perimeter. Twice the sum of the sides: 2 * (this.width + this.height). The parentheses make the addition happen first.
    5. Square test. A comparison is already a boolean, so this.width === this.height can be returned directly, with no if.

    The solution in TypeScript

    class Rectangle {
        width: number;
        height: number;
    
        constructor(width: number, height: number) {
            this.width = width;
            this.height = height;
        }
    
        area(): number {
            return this.width * this.height;
        }
    
        perimeter(): number {
            return 2 * (this.width + this.height);
        }
    
        isSquare(): boolean {
            return this.width === this.height;
        }
    }
    

    A few details:

    • this. Inside a method, this is the object the method was called on. Without it, width would mean the constructor's parameter, which no longer exists once the constructor ends.
    • Types are only for the compiler. number annotations are checked when you compile and then erased: the JavaScript that runs has no types.
    • === compares without converting. For two numbers it is true exactly when they are equal.

    Using the class

    const r = new Rectangle(3, 4);
    console.log(r.area(), r.perimeter(), r.isSquare());
    const s = new Rectangle(5, 5);
    console.log(s.area(), s.perimeter(), s.isSquare());
    const a = new Rectangle(2, 10);
    const b = new Rectangle(10, 2);
    console.log(a.area(), a.perimeter(), a.isSquare());
    console.log(b.area(), b.perimeter(), b.isSquare());
    console.log(a.width, b.width);
    

    This prints:

    12 14 false
    25 20 true
    20 24 false
    20 24 false
    2 10
    

    The lesson's tests print the booleans as True and False; TypeScript itself prints true and false. The last line shows that a and b each keep their own width. Turning a rectangle on its side changes neither its area nor its perimeter.

    Why a class instead of functions

    You could write area(width, height) as a plain function and pass the two numbers every time. That works for one rectangle, but the caller must carry the sizes around and keep each pair together. A class moves that bookkeeping into the object: you create the rectangle once, and afterwards you only ask it questions. The methods get the numbers from this, so you never pass them again.

    When the code is compiled for ES2022, the class stays a JavaScript class. The two field declarations remain as fields of the object, and the types disappear. After new Rectangle(3, 4), the object's own properties are exactly width and height, in that order. The methods live on the class and are shared by all rectangles.

    Testing

    Try the smallest and the largest sizes in the constraints:

    • new Rectangle(1, 1) gives area 1, perimeter 4, and true.
    • new Rectangle(1, 10000) gives area 10000, perimeter 20002, and false.
    • new Rectangle(10000, 10000) gives area 100000000, perimeter 40000, and true.

    Even the largest area, 100 million, is far below the largest integer a number holds exactly (2 to the power 53), so no overflow worries here.

    Another way: parameter properties

    TypeScript has a shortcut for the pattern "declare a field, then copy the parameter into it". Putting a modifier such as public in front of a constructor parameter declares the field and assigns it in one go:

    class Rectangle {
        constructor(public width: number, public height: number) {}
        area(): number { return this.width * this.height; }
    }
    const r = new Rectangle(3, 4);
    console.log(r.width, r.height, r.area());
    

    This prints 3 4 12. The lesson builds the longer form on purpose, so that you see the three separate things a constructor does: receive the arguments, name the fields, store the values.

    Edge cases and common mistakes

    • Forgetting this.. Writing return width * height; inside area() refers to names that don't exist there, and the compiler reports it.
    • Perimeter without parentheses. 2 * this.width + this.height doubles only the width. For a 3 by 4 rectangle it gives 10 instead of 14.
    • Using == or an if for the square test. === is the idiomatic comparison for numbers, and an if that returns true or false only repeats the comparison.
    • Sharing state. Keep the sizes in fields, not in variables outside the class, or every rectangle would see the same numbers.

    Key points

    • A class describes what every object of that kind has: fields for the data and methods for the questions.
    • The constructor runs once for each new and gives the object its starting values.
    • Each object has its own copy of the fields, so objects built from the same class stay independent.
    • A method that only reads fields and does one calculation, like all three here, runs in constant time.
    • Returning a comparison directly is clearer than wrapping it in an if that returns true or false.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free