Part 2 - Master the Basics of TypeScript for Effective Playwright Automation
- Anuradha Agarwal
- Feb 9
- 8 min read
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