TypeScript Cheat Sheet — The Essentials¶
Who this is for: A QA / test engineer who needs just enough TypeScript to read and write Playwright (or any TS) tests. Skim it once, keep it open as a reference. TypeScript = JavaScript + types (labels that catch mistakes before you run the code).
1. Why Types At All?¶
The type label means your editor flags typos, wrong arguments, and undefined bugs as you type, instead of 10 minutes into a test run.
2. Basic Types¶
let name: string = "Manoj";
let age: number = 42;
let isActive: boolean = true;
let nothing: null = null;
let notSet: undefined = undefined;
let anything: any = "avoid this"; // turns OFF type-checking — avoid
let id: number; // declare type, assign later
id = 100;
// Arrays
let scores: number[] = [90, 85, 100];
let names: string[] = ["a", "b"];
// Tuple — fixed-length, typed positions
let pair: [string, number] = ["age", 42];
3. Type Inference (you often don't need to write types)¶
let city = "London"; // TS infers: string
let total = 10 + 5; // TS infers: number
// city = 42; // ❌ still caught, even without an explicit type
Rule of thumb: let TS infer simple variables; write explicit types on function parameters and object shapes.
4. Functions¶
// parameter types + return type
function add(a: number, b: number): number {
return a + b;
}
// arrow function
const greet = (name: string): string => `Hello, ${name}`;
// optional parameter (?) and default value
function log(msg: string, level?: string) {} // level may be undefined
function pageSize(n: number = 20): number { return n; } // default 20
// returns nothing
function printIt(x: string): void {
console.log(x);
}
// async function returns a Promise
async function fetchUser(id: number): Promise<string> {
return "user";
}
5. Objects, type, and interface¶
Two ways to describe an object's shape. Both work; interface is common for objects, type for everything (unions, primitives, etc.).
// interface
interface User {
name: string;
age: number;
email?: string; // optional
readonly id: number; // can't be reassigned after creation
}
// type alias
type Point = { x: number; y: number };
const u: User = { name: "Jane", age: 30, id: 1 };
const p: Point = { x: 10, y: 20 };
interface |
type |
|
|---|---|---|
| Describe object shape | ✅ | ✅ |
Unions (A \| B) |
❌ | ✅ |
| Can be extended/merged | ✅ (re-declare) | via & |
| Common use | Objects, classes | Unions, primitives, functions |
6. Union & Literal Types¶
let id: string | number; // EITHER a string OR a number
id = "abc"; id = 123; // both fine
// literal union — only these exact values allowed
type Status = "pass" | "fail" | "skip";
let result: Status = "pass";
// result = "broken"; // ❌ not an allowed value
This is huge for tests: reporter: "html" | "list" | "junit" stops typos at write time.
7. Arrays of Objects & Record¶
interface TestCase { id: number; name: string; }
const cases: TestCase[] = [
{ id: 1, name: "login" },
{ id: 2, name: "logout" },
];
// Record<Keys, ValueType> — a typed dictionary/map
const env: Record<string, string> = {
BASE_URL: "https://staging",
TOKEN: "abc123",
};
8. Classes (Page Objects use these)¶
class LoginPage {
// properties with access modifiers
private url: string;
readonly name: string = "Login";
constructor(url: string) {
this.url = url;
}
// method
open(): void {
console.log(`Opening ${this.url}`);
}
}
// inheritance
class AdminPage extends LoginPage {
constructor() {
super("/admin");
}
}
const page = new LoginPage("/login");
page.open();
| Modifier | Meaning |
|---|---|
public (default) |
Accessible anywhere |
private |
Only inside this class |
protected |
This class + subclasses |
readonly |
Set once, never reassigned |
9. Generics — <T> (reusable, type-safe code)¶
A placeholder type filled in when used. You'll read these constantly in Playwright (Promise<void>, Locator, test.extend<MyFixtures>).
function first<T>(items: T[]): T {
return items[0];
}
first<number>([1, 2, 3]); // T = number → returns number
first(["a", "b"]); // T inferred as string
// Promise<T> — an async value of type T
async function getCount(): Promise<number> {
return 5;
}
10. Handling null / undefined (the safety stuff)¶
let val: string | undefined;
// optional chaining ?. — stop if null/undefined, don't crash
const len = val?.length; // number | undefined
// nullish coalescing ?? — fallback ONLY when null/undefined
const name = val ?? "default"; // "default" if val is null/undefined
// non-null assertion ! — "trust me, it's not null" (use sparingly)
const sure = val!.length; // tells TS to stop worrying
11. Imports & Exports (how files connect)¶
// named export
export const BASE_URL = "https://app.com";
export function login() {}
// import named things
import { BASE_URL, login } from "./config";
// default export (one per file)
export default class LoginPage {}
import LoginPage from "./LoginPage";
// import everything
import * as utils from "./utils";
// type-only import (clarity / perf)
import type { User } from "./types";
12. Common Playwright + TypeScript Patterns¶
import { test, expect, Page, Locator } from '@playwright/test';
// typed Page Object
class CartPage {
readonly checkoutBtn: Locator;
constructor(public page: Page) {
this.checkoutBtn = page.getByRole('button', { name: 'Checkout' });
}
async checkout(): Promise<void> {
await this.checkoutBtn.click();
}
}
// async/await — almost everything in Playwright is async
test('adds item', async ({ page }) => {
await page.goto('/'); // await = wait for it to finish
const title: string = await page.title();
expect(title).toContain('Shop');
});
// typed test data array (data-driven)
const users: { name: string; valid: boolean }[] = [
{ name: 'standard', valid: true },
{ name: 'locked', valid: false },
];
for (const u of users) {
test(`login: ${u.name}`, async ({ page }) => { /* ... */ });
}
13. Quick Symbol Reference¶
| Symbol | Meaning | Example |
|---|---|---|
: |
type annotation | name: string |
? |
optional | email?: string |
\| |
union (or) | string \| number |
& |
intersection (and) | A & B |
=> |
arrow function | (x) => x + 1 |
?. |
optional chaining | user?.name |
?? |
nullish fallback | x ?? "default" |
! |
non-null assertion | value! |
<T> |
generic type | Array<string> |
readonly |
can't reassign | readonly id: number |
as |
type assertion | x as string |
... |
spread / rest | [...arr], (...args) |
`${}` |
template string | `Hi ${name}` |
14. The 5 Things You'll Use 90% of the Time¶
async / await— Playwright is asynchronous; almost every action needsawait.interface/type— describe your test data and page shapes.- Union literals —
"pass" | "fail"to constrain values. - Classes — Page Objects are classes.
?.and??— handle values that might be missing without crashing.
15. Where to Go Next¶
- Playwright Framework Tutorial — see these types used in a real framework
- Playwright Project Anatomy — where
tsconfig.jsonfits in - Official handbook: typescriptlang.org/docs — the TypeScript for JavaScript Programmers page