Real World Example

Typed Analytics Events

Product analytics (Mixpanel, Amplitude, Google Analytics at Zomato, CRED, Netflix) track hundreds of events, each with its own properties. A single map type, together with keyof and indexed access, makes every track call type-checked.

Example

type AnalyticsEvents = {
  product_viewed: { productId: number; source: "search" | "home" | "ad" };
  added_to_cart: { productId: number; qty: number; price: number };
  checkout_started: { cartValue: number; items: number };
  payment_failed: { reason: string; method: "upi" | "card" };
};

type EventName = keyof AnalyticsEvents;
const sent: string[] = [];

function track<E extends EventName>(event: E, props: AnalyticsEvents[E]): void {
  sent.push(`${event} ${JSON.stringify(props)}`);
}

track("product_viewed", { productId: 42, source: "search" });
track("added_to_cart", { productId: 42, qty: 1, price: 1299 });
track("checkout_started", { cartValue: 1299, items: 1 });
track("payment_failed", { reason: "bank timeout", method: "upi" });

sent.forEach((line) => console.log(line));

Output

product_viewed {"productId":42,"source":"search"}
added_to_cart {"productId":42,"qty":1,"price":1299}
checkout_started {"cartValue":1299,"items":1}
payment_failed {"reason":"bank timeout","method":"upi"}

Catching a Wrong Property

A wrong property for an event is caught immediately (TS2353).

type AnalyticsEvents = { added_to_cart: { productId: number; qty: number } };
function track<E extends keyof AnalyticsEvents>(event: E, props: AnalyticsEvents[E]): void {}

track("added_to_cart", { productId: 42, quantity: 1 });

Compiler output (tsc)

Line 4: error TS2353: Object literal may only specify known properties, and 'quantity' does not exist in type '{ productId: number; qty: number; }'.