top of page

Part 2 - Master the Basics of TypeScript for Effective Playwright Automation

Updated: Feb 10


In the previous part-1 post, we set up the complete TypeScript development environment required for learning modern automation tools like Playwright. This included installing Node.js, configuring Visual Studio Code, and creating a clean TypeScript project structure with src, dist, and a minimal tsconfig.json. At this stage, we focused only on preparing a solid TypeScript learning setup, without installing Playwright itself.

With the environment now ready, the next important step is to understand TypeScript fundamentals. TypeScript is the language most commonly used with Playwright, so building a strong foundation here will make learning Playwright automation much easier later.


This post is designed for absolute beginners. No prior JavaScript knowledge is required. Each concept is explained step by step using simple TypeScript examples, and wherever useful, we also compare the same code in JavaScript vs TypeScript. This side-by-side approach helps you clearly understand what TypeScript adds on top of JavaScript and why it is preferred in modern test automation projects.


In this TypeScript fundamentals tutorial, we cover the core building blocks you will use repeatedly when writing Playwright tests: variables, data types, arrays, objects, operators, and conditional statements (if/else and switch). These concepts form the foundation for handling test data, writing conditions, and controlling test flow in automation scripts.

By the end of this post, you will have a solid understanding of TypeScript basics and a clear picture of how JavaScript and TypeScript differ.



Section - Variable Declaration: JavaScript First, Then TypeScript


Before learning TypeScript, it’s important to understand how variables work in JavaScript, because TypeScript is built on top of JavaScript.Everything you write in TypeScript ultimately becomes JavaScript.


Variable Declaration in JavaScript

In JavaScript, variables can be declared using var, let, or const.

// JavaScript variable declaration
let username = "Anuradha";
const age = 35;
var isActive = true;

What these keywords mean:

  • let → value can be changed later

  • const → value cannot be reassigned

  • var → older keyword (not recommended in modern code)

Note: In modern JavaScript, let and const are preferred.var is mostly avoided due to scope and hoisting issues.

JavaScript Decides Types at Runtime


A key characteristic of JavaScript is that variable types are not fixed.The type is determined at runtime.

This means you can accidentally change the type of a variable later.

let score = 90;

console.log("before type of score", typeof score);

score = "ninety";

console.log("after type of score", typeof score);

Output:

before type of score number
after type of score string

⚠️ This behavior is allowed in JavaScript.


JavaScript does not stop you from changing a number into a string. In small scripts this may look harmless, but in larger applications and automation frameworks, this can cause subtle and hard-to-debug issues.


The Problem with This Approach

In JavaScript:

  • There is no warning before running the code

  • Errors appear only at runtime

  • Bugs may surface late during execution

This is one of the main reasons why modern projects prefer TypeScript.


The Same Example in TypeScript

Now let’s see how TypeScript handles the same scenario.

let score = 90;

// score = "ninety"; // ❌ Compile-time error

What happens here:

  • TypeScript infers that score is a number

  • Reassigning a string is not allowed

  • The error is caught before the code runs

💡 This is called type safety, and it is one of the biggest advantages of TypeScript.

Explicit Type Declaration in TypeScript

You can also explicitly declare the type to make your intent very clear.

let score: number = 90;

// score = "ninety"; // ❌ Compile-time error

This makes your code:

  • Easier to understand

  • Safer to maintain

  • More predictable in large projects

let and const in TypeScript

TypeScript uses let and const exactly the same way as JavaScript.

let total = 100;
total = 120;   // allowed

const maxScore = 100;
// maxScore = 120; // ❌ Error – cannot reassign

Best Practice (JavaScript & TypeScript)

  • Use const by default

  • Use let only when reassignment is needed


Side Note: null vs undefined in Variables

Although both represent “no value”, they mean different things in TypeScript.

let token: string | undefined; // value not assigned yet
let response: string | null = null; // intentionally empty

  • undefined → value not provided or not set yet

  • null → value intentionally cleared


TypeScript forces you to handle these cases explicitly, making your code more honest and safer.


JavaScript vs TypeScript: Variable Behavior

Feature

JavaScript

TypeScript

Variable keywords

var, let, const

let, const

Type checking

Runtime

Compile time

Accidental type change

Allowed

Not allowed

Error detection

Late

Early

Why This Matters for Playwright Automation

Playwright tests rely heavily on variables for:

  • Test data

  • Configuration values

  • Function parameters

  • API responses


Using TypeScript ensures:

  • Wrong values are caught early

  • Fewer runtime test failures

  • Better auto-complete and hints in VS Code


This is why TypeScript is the preferred and modern choice for Playwright automation.


✅ Key Takeaway

  • JavaScript allows flexible typing, which can cause hidden bugs

  • TypeScript adds safety by fixing types early

  • Syntax looks similar, but behaviour is very different

  • Learning this now makes Playwright much easier later


Next section: Data Types in TypeScript


Section: Data Types in TypeScript


In the previous section, we learned how variables work in JavaScript and how TypeScript adds type safety. Now, let’s understand data types in TypeScript, which define what kind of values a variable is allowed to store.


Unlike JavaScript, TypeScript checks data types before the code runs, helping you catch mistakes early.


1️⃣ Primitive Data Types in TypeScript


These are the most commonly used and most important data types.

string – Text Values

let username: string = "Anuradha";
let city = "Dubai"; // type inferred as string

Note: Since , we declared a variable "city" in previous script for var, we will get an error like below:



When multiple TypeScript files are compiled together, variables declared at the top level share a global scope.To avoid naming conflicts, make each file a module by adding:
export {};

In Playwright:

  • Each test file is a module

  • Imports/exports are always used

  • This problem almost never happens

But in learning TypeScript basics, it’s very common

Let's get back to data type string


Used for:

  • URLs

  • Usernames

  • Selectors

  • Messages


number – Numeric Values

let age: number = 35;
let timeout = 5000; // inferred as number

Includes:

  • integers

  • decimals

  • negative numbers

❌ Invalid assignment:

// age = "thirty five"; // Error

boolean – True / False

let isLoggedIn: boolean = true;
let hasError = false; // inferred

Used heavily in:

  • Conditions

  • Flags

  • Test validations


2️⃣ Arrays in TypeScript


An array is a data structure used to store multiple values in a single variable.

Arrays are commonly used for:

  • Lists of items

  • Test data

  • Multiple values of the same type


In JavaScript, arrays can hold mixed data types.

let data = ["chromium", 3, true, null];

This flexibility is allowed, but it can lead to unexpected bugs, especially in large applications and automation frameworks.


In TypeScript, arrays are typed, meaning all elements must follow the same data type.

This makes your code safer and more predictable.


Array of strings

let browsers: string[] = ["chromium", "firefox", "webkit"];

Array of numbers

let scores: number[] = [90, 85, 88];

❌ Not allowed:

// browsers.push(123); // Error

Alternative Array Syntax

let retries: Array<number> = [1, 2, 3];

Both styles are valid — type[] is more common.



3️⃣ Objects in JavaScript and TypeScript


An object is a data structure that stores related values as key–value pairs.


Objects are used everywhere in real projects:

  • User data

  • Configuration files

  • API requests and responses

  • Test data models


Objects in JavaScript

In JavaScript, objects are flexible but not type-safe.

let user = {
  name: "Anuradha",
  age: 35,
  isAdmin: true
};

JavaScript allows you to:

  • Add new properties

  • Change value types

  • Miss required fields

user.age = "thirty five"; // allowed
user.city = "Dubai";     // allowed

Objects in TypeScript


In TypeScript, objects can be strictly typed, which means:

  • Property names are fixed

  • Property types are enforced

  • Missing or extra fields are caught early

let user: {
  name: string;
  age: number;
  isAdmin: boolean;
} = {
  name: "Anuradha",
  age: 35,
  isAdmin: true
};

❌ Not allowed:

// user.age = "thirty five"; // Error
// user.city = "Dubai";     // Error

Optional Properties in Objects

Some object properties may not always be present.

let user: {
  name: string;
  age?: number;
} = {
  name: "Anuradha"
};

👉 age? means the property is optional.

Read-Only Object Properties

let config: {
  readonly baseUrl: string;
  timeout: number;
} = {
  baseUrl: "https://example.com",
  timeout: 5000
};

// config.baseUrl = "https://test.com"; // ❌ Error

Useful for:

  • Environment configs

  • Constants

  • Test settings


Objects with Arrays (Very Common)

let testUser: {
  name: string;
  roles: string[];
} = {
  name: "Anuradha",
  roles: ["admin", "editor"]
};

Why Objects Matter in Playwright


Playwright heavily uses objects:

await page.goto("https://example.com", {
  timeout: 5000,
  waitUntil: "networkidle"
});
expect(response).toMatchObject({
  status: 200
});

Typed objects make:

  • API usage safer

  • Code self-documenting

  • Refactoring easier


JavaScript vs TypeScript: Objects

Feature

JavaScript

TypeScript

Property validation

Missing fields

Allowed

Extra fields

Allowed

IDE auto-complete

Limited

Excellent


Section: Operators in TypeScript


Operators are used to perform actions on values and variables — such as calculations, comparisons, and logical checks.

Before writing conditions or functions, it’s important to understand operators clearly.


1️⃣ Arithmetic Operators


Used for mathematical calculations.

JavaScript Example

let a = 10;
let b = 3;

console.log(a + b); // 13
console.log(a - b); // 7
console.log(a * b); // 30
console.log(a / b); // 3.333...

JavaScript allows operations even when types are mixed.

console.log(10 + "5"); // "105" (string concatenation)

TypeScript Example

let a: number = 10;
let b: number = 3;

console.log(a + b);
// console.log(a + "5"); // "105" → string concatenation

The + operator is special in JavaScript.


When one operand is a string, JavaScript performs string concatenation, and TypeScript allows this behavior.


let a: number = 10;


// a = a + true; // ❌ Error

// a = a + undefined; // ❌ Error

// a > "5"; // ❌ Error

This reinforces:


TS protects you where JS behavior is unsafe or unclear



2️⃣ Assignment Operators


Used to assign and update values.

let score = 80;

score = score + 10;
score += 5;

console.log(score); // 95

3️⃣ Comparison Operators

Used to compare values.Result is always a boolean.

let x = 10;
let y = 20;

console.log(x > y);   // false
console.log(x < y);   // true
console.log(x >= 10); // true

Equality: == vs === (Very Important)

console.log(5 == "5");  // true  (type coercion)
console.log(5 === "5"); // false (strict check)

This will give a compile error in ts code as the number is compared to a string but in JS it will produce the above result


4️⃣ Logical Operators


Used in conditions.

let isLoggedIn = true;
let isAdmin = false;

console.log(isLoggedIn && isAdmin); // false
console.log(isLoggedIn || isAdmin); // true
console.log(!isAdmin);              // true

5️⃣ Ternary Operator


A compact if–else.

let age = 20;

let access = age >= 18 ? "Allowed" : "Denied";
console.log(access);

Conditional Statements in JavaScript and TypeScript


Conditional statements allow your program to make decisions based on conditions.

They are heavily used in:

  • Test validations

  • Control flow

  • Retry logic

  • Environment-based behaviour


1️⃣ if Statement

let age: number = 20;
if (age >= 18) {
  console.log("Access granted");
}

2️⃣ if – else


let score: number = 65;
if (score >= 60) {
  console.log("Pass");
} 
else {
  console.log("Fail");
}

3️⃣ if – else if – else

let marks: number = 82;
if (marks >= 90) {
  console.log("Grade A");
} 
else if (marks >= 75) {
  console.log("Grade B");
} 
else {
  console.log("Grade C");
}

Why Conditionals Matter in Playwright

if (await page.isVisible("#login")) {
  await page.click("#login");
}
if (response.status() !== 200) {
  throw new Error("API failed");
}

Conditionals control test flow and fail-fast behavior.


Switch Statement in JavaScript and TypeScript


The switch statement is used when you need to compare one value against many cases.

It is often cleaner than multiple else if blocks. Syntax is the same in JS and TS


let role: string = "user";


switch (role) {

case "admin":

console.log("Admin access");

break;


case "user":

console.log("User access");

break;


case "guest":

console.log("Guest access");

break;


default:

console.log("Unknown role");

}

TypeScript ensures only valid values are used.


Why switch Matters in Playwright

switch (process.env.ENV) {
  case "qa":
    baseUrl = "https://qa.example.com";
    break;
  case "prod":
    baseUrl = "https://example.com";
    break;
}

In this post, we covered the core building blocks of TypeScript, starting from JavaScript basics and gradually adding TypeScript’s safety layer.


What You Learned in This Post

  • How variables work in JavaScript and TypeScript

  • Data types in TypeScript (string, number, boolean, arrays, objects)

  • Special types (any, unknown, null, undefined)

  • Operators and common pitfalls (+, == vs ===)

  • Conditional statements (if, else, switch)

  • How TypeScript catches logical mistakes early


Next Post


In the next post, we will continue advancing our TypeScript knowledge by exploring slightly more advanced fundamentals, including functions, loops, type aliases, interfaces, and union types. These topics are essential for writing clean, reusable, and maintainable code.


Only after completing these TypeScript fundamentals we will dive into Playwright. This step-by-step approach ensures that when we start writing Playwright tests, the focus remains on automation concepts, not on struggling with the language itself. So lets continue with next post - Master the Basics of TypeScript for Effective Playwright Automation - Part 3


Comments


Never Miss a Post. Subscribe Now!

Thanks for submitting!

©anuradha agarwal

    bottom of page