Type challenges
Nine interview-level typing tasks with tests and hidden solutions.
Nine tasks interviewers actually assign. Each starts broken — make the
tests green with zero type errors, no any, no ignore comments, no !.
Then peek at one possible solution. All checks run in the page; nothing
leaves your browser.
1. first of any array
Checked with TypeScript 6.0.3, strict mode
function first(items: number[]): number {
return items[0];
}2. cart reducer
Checked with TypeScript 6.0.3, strict mode
type CartAction = { kind: "add"; amount: number } | { kind: "reset" };
function reduceCart(total: number, action: CartAction): number {
if (action.kind === "add") {
return total + action.amount;
}
return total + action.amount;
}3. safe display name
Checked with TypeScript 6.0.3, strict mode
function displayName(raw: unknown): string {
const record = raw as { name: string };
return record.name;
}4. typed event bus
Checked with TypeScript 6.0.3, strict mode
type Handler = (message: string) => void;
class Bus {
private handlers: unknown[] = [];
on(handler: Handler): void {
this.handlers.push(handler);
}
emit(message: string): void {
for (const handler of this.handlers) {
handler(message);
}
}
}5. partial from scratch
Checked with TypeScript 6.0.3, strict mode
type MyPartial<T> = T;6. rescue legacy total
Checked with TypeScript 6.0.3, strict mode
function total(prices) {
let sum = 0;
for (const price of prices) {
sum = sum + price;
}
return sum;
}7. typed fetch
Checked with TypeScript 6.0.3, strict mode
interface ApiUser {
id: number;
name: string;
}
async function getUser(id: number): Promise<ApiUser> {
const response = await fakeFetch("https://api.example.com/users/" + id);
return response;
}8. rename without mutating
Checked with TypeScript 6.0.3, strict mode
interface CartItem {
readonly id: number;
name: string;
price: number;
}
function rename(items: CartItem[], id: number, name: string): CartItem[] {
for (const item of items) {
if (item.id === id) {
item.name = name;
}
}
return items;
}9. exhaustive status labels
Checked with TypeScript 6.0.3, strict mode
type Status = "new" | "paid" | "shipped";
function label(status: Status): string {
if (status === "new") {
return "fresh order";
}
return "money in";
}