top of page

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

Updated: Apr 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)

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 behaviour 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.


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 the 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 rarely happens


But in learning TypeScript basics, it’s very common


Let's get back to the 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


Arrays in TypeScript


Now, let’s understand arrays.


In automation, we often need to store multiple related values together. For example, suppose we want to test a login feature with multiple usernames, or we want to search for different keywords in our application.

Instead of creating separate variables for each value, it is much easier to store all values in one place.

For example, multiple search keywords:

let searchKeywords = ["organic", "fresh", "grocery"];

Or multiple test input values:

let quantities = [1, 2, 5, 10];

In such situations, we use an array.


An array allows us to store multiple values inside a single variable.

So instead of writing:

let keyword1 = "organic";
let keyword2 = "fresh";
let keyword3 = "grocery";

We can simply write:

let searchKeywords = ["organic", "fresh", "grocery"];

All related values are now grouped into a single variable.


Arrays are commonly used to manage a collection of related data.

For example:

multiple search inputs

list of URLs

test data values

multiple user roles

configuration values


Arrays in JavaScript


In JavaScript, arrays can store mixed data types.

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

JavaScript allows this flexibility.


However, in automation frameworks, mixed data types can sometimes create confusion and unexpected bugs.


Arrays in TypeScript

In TypeScript, we usually define the type of values the array should contain.

Example:

let searchKeywords: string[] = ["organic", "fresh", "grocery"];
let quantities: number[] = [1, 2, 5, 10];

Here, TypeScript ensures that all values inside the array follow the same data type.

Incorrect example:

// quantities.push("ten"); Error

Alternative syntax

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

Both styles are valid.


Objects in TypeScript


Now, let’s understand objects.

In automation, we often need to store multiple related pieces of information about one entity.


For example, suppose we want to store details of a test user.

A user may have:

name

email

role

login status

Instead of creating multiple separate variables, it is better to group all related information together in one structure.

This is where objects are used.

An object allows us to store data in key–value pairs, where each value is associated with a meaningful name.

Example:

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

Here:

name, age, isAdmin → keys

"Anuradha", 35, true → values

All related information is stored in a single variable called user.

This makes the code:


Objects are used everywhere in real automation projects.

For example:

user data

configuration settings

API request data

API response validation

test data models

Objects in JavaScript

In JavaScript, objects are very flexible.

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

JavaScript allows us to:


Add new properties later

user.city = "Dubai";

change value types

user.age = "thirty five";

JavaScript does not stop us from making such changes.


While this flexibility is useful, it may sometimes lead to unexpected bugs.


Objects in TypeScript


In TypeScript, objects can be strictly typed.


This means we clearly define:

what properties the object should contain, what type of value each property should store

Example:

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

Now TypeScript ensures:

Property names remain fixed
Property types remain correct
Incorrect changes are not allowed:
// user.age = "thirty five"; ❌ Error
// user.city = "Dubai"; ❌ Error

TypeScript catches such issues before the code runs.


This makes the code safer and more predictable.


Optional properties in objects


Sometimes, certain information may not always be available.

Example: age may not always be provided.


TypeScript allows optional properties using ?

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

Here:

Age is optional.

This means the object can exist even if age is not provided.


Read-only properties


Some values should never change once defined.

Example: application base URL or configuration settings.

TypeScript allows readonly properties.

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

Incorrect change:

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

Readonly properties are useful for:

environment configuration

constants

test settings

Objects containing arrays

Very common in automation:

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

Here roles is an array inside an object.

Such structures are frequently used in test data.


Why objects are important in Playwright

Playwright uses objects extensively.

Example:

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

Here the second parameter is an object containing configuration options.

Another example:

expect(response).toMatchObject({ status: 200});

Objects help us structure data clearly.

Typed objects make:

API usage safer

code easier to understand

refactoring easier


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);

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



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");
}

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