TypeDrop
2026-07-04 Challenge
2026-07-04
Easy
Typed Event RSVP Aggregator
You're building the RSVP processing module for an event management platform. Raw RSVP submissions arrive as `unknown` from a webhook; your module must validate them into strongly-typed `Rsvp` records, tally responses by status, and return a fully-typed `RsvpSummary` — with zero `any`.
Goals
- Define the `Rsvp`, `Result<T>`, and `RsvpSummary` types with correct field types and constraints.
- Implement `parseRsvp` to validate an `unknown` payload into a `Result<Rsvp>`, returning a failure Result for any invalid field.
- Implement `aggregateRsvps` to silently skip invalid or mismatched payloads and return an `RsvpSummary` with a complete `Record<RsvpStatus, number>` — defaulting all statuses to 0.
- Use `Record<RsvpStatus, number>` so the compiler enforces that every status is always present in the counts map.
challenge.ts
/** The three possible RSVP responses an attendee can give. */
type RsvpStatus = "attending" | "declined" | "maybe";
/** A validated RSVP record. */
type Rsvp = {
id: string;
eventId: string;
name: string;
email: string;
status: RsvpStatus;
guests: number;
};
/** Success-or-failure wrapper — no exceptions thrown. */
type Result<T> =
| { ok: true; value: T }
| { ok: false; error: string };
/** Per-status tally for a single event. */
type RsvpSummary = {
eventId: string;
counts: Record<RsvpStatus, number>;
totalGuests: number;
};
// Validate a raw webhook payload into a typed Rsvp
declare function parseRsvp(raw: unknown): Result<Rsvp>;
// Aggregate an array of raw payloads for one event
declare function aggregateRsvps(eventId: string, raws: unknown[]): RsvpSummary;
Hints (click to reveal)
Hints
- To check that a string is a valid `RsvpStatus`, create a constant array `const STATUSES = ['attending', 'declined', 'maybe'] as const` and use `Array.prototype.includes` — you may need a small helper to satisfy the type checker.
- Build the initial `counts` object using `Object.fromEntries` over the known statuses so TypeScript infers `Record<RsvpStatus, number>` without casting.
- When narrowing `unknown`, check `typeof raw === 'object' && raw !== null` first, then use the `in` operator to verify each key exists before accessing it.
Useful resources
Or clone locally
git clone -b challenge/2026-07-04 https://github.com/niltonheck/typedrop.git