Day 42 of 100: Generic Constraints — extends and keyof
Day 42 of 100 — 100 Days of Playwright with TypeScript Challenge. Phase: TypeScript. JavaScript (Days 1-33) → TypeScript (Days 34-63) → Playwright (Days 64-96) → AI Framework Capstone (Days 97-100).
🎭 Want to master this with real projects? Join the Playwright Automation Mastery course at The Testing Academy.
Unconstrained T accepts anything. extends constrains it — so your helper can safely use T’s properties.
Contents
The extends Constraint
// T must have an id — now .id access is legal inside:
function byId(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
const users = [{ id: 1, name: 'Jane' }, { id: 2, name: 'Raj' }];
byId(users, 2)?.name; // 'Raj' — full User type preserved
// byId(['a','b'], 1) — error: string lacks id
🚀 Level Up Your Playwright
From locators to CI pipelines — build a production-grade Playwright + TypeScript framework step by step.
keyof Constraint — Typed Property Access
function pluck(items: T[], key: K): T[K][] {
return items.map(item => item[key]);
}
const names = pluck(users, 'name'); // string[]
const ids = pluck(users, 'id'); // number[]
// pluck(users, 'email') — error: not a key of User
QA Pattern: Constrained Cleanup Registry
type Deletable = { id: number };
class Cleanup {
private items: T[] = [];
track(item: T) { this.items.push(item); return item; }
async run(del: (id: number) => Promise) {
for (const item of this.items.reverse()) await del(item.id);
}
}
// Track created users/orders, delete in reverse order after the test.
Tomorrow (Day 43): Classes in TypeScript — typed Page Objects.
🎓 Master Playwright End to End
Join hundreds of SDETs building real automation frameworks. Lifetime access, hands-on projects, and a job-ready portfolio.
