A/B Testing in TypeScript: How to Stop Guessing

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Life Before A/B Tests: Why Intuition Fails

Have you ever argued with a designer about which button is better — red or blue? Or with a manager about which headline will get more clicks? In the past, such disputes were settled by the loudest voice or by hierarchy. Today we have A/B testing in TypeScript — a scientific method that turns guesses into data.

Imagine: you launch an online store. It seems that adding reviews to the product card will increase sales. What if you remove the image carousel and leave one large photo? Without split testing, you will never know the truth. This is where TypeScript comes to the rescue — strict typing and modern tools make A/B tests reliable and convenient.



What is A/B Testing in Simple Terms

An A/B test (also known as a split test) is an experiment in which two groups of users are shown different versions of the same element. The control group (A) sees the current version, the experimental group (B) sees the modified one. Then we compare metrics: conversion rate, time on site, clicks.

Why is this important? Because even experienced product managers are wrong 70% of the time. Hypothesis testing with A/B tests allows you to make decisions based on data, not intuition. TypeScript adds type safety and development convenience to this.



How A/B Testing Works in TypeScript Applications

In TypeScript applications, A/B testing is typically implemented through:

  • User assignment — which variant to show to a specific user
  • Event tracking — collecting data on user actions
  • Result analysis — calculating statistical significance


Let's look at each stage with an example. Suppose we want to test a new headline on the login page. Here's what it looks like in code:



// Define types for the experimenttype ExperimentVariant = 'control' | 'variant';type ExperimentConfig = {  id: string;  variants: ExperimentVariant[];  weights: number[]; // sum must be 100};

// A/B test configurationconst headlineExperiment: ExperimentConfig = { id: 'headline_test_2024', variants: ['control', 'variant'], weights: [50, 50] // 50% see the old headline, 50% see the new one};

// Random assignment functionfunction assignVariant(config: ExperimentConfig): ExperimentVariant { const random = Math.random() * 100; let cumulativeWeight = 0; for (let i = 0; i < config.variants.length; i++) { cumulativeWeight += config.weights[i]; if (random < cumulativeWeight) { return config.variants[i]; } } return config.variants[0]; // fallback}

// Usageconst userVariant = assignVariant(headlineExperiment);console.log(`User will receive variant: ${userVariant}`);


User Segmentation: To Avoid Confusion

It is important that a single user always sees the same variant. Otherwise, the data will be corrupted. For this, we use a user ID or cookies:



function getStableVariant(  userId: string,   config: ExperimentConfig): ExperimentVariant {  // Use a hash of userId for deterministic assignment  const hash = simpleHash(userId + config.id);  const normalizedHash = hash % 100;    let cumulativeWeight = 0;  for (let i = 0; i < config.variants.length; i++) {    cumulativeWeight += config.weights[i];    if (normalizedHash < cumulativeWeight) {      return config.variants[i];    }  }    return config.variants[0];}

function simpleHash(str: string): number { let hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash |= 0; // Conv

Blogs

Book Recommendations