Let's think about this for a second
This set is tougher than Set 1 — you'll be combining concepts like union types, type narrowing, generics, and classes from the tutorial's Intermediate and Advanced chapters to solve real problems. Each task blends more than one concept together with earlier ones, so pause and think for a few seconds before you start coding. Don't panic if a compiler error shows up — reading the error message and debugging where the type mismatch is happening is itself an important part of learning TypeScript.
Exercises
Task 1: Define a type Shape as the union { kind: "circle"; radius: number } | { kind: "square"; side: number }, and write a function getArea(shape: Shape): number that narrows on kind to calculate the area. Task 2: Create a generic class Stack<T> and implement the methods push(item: T): void, pop(): T | undefined, and peek(): T | undefined. Task 3: Create a base class Animal, extend it with a Dog class, and override the method makeSound(): string (Dog's makeSound() should return "Woof"). Task 4: Write a type guard function isString(value: unknown): value is string, and use it to filter only the string values out of an unknown[] array.
Sample code
// Task 1
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function getArea(shape: Shape): number {
// TODO: narrow by shape.kind
return 0;
}
// Task 2
class Stack<T> {
private items: T[] = [];
push(item: T): void {
// TODO
}
pop(): T | undefined {
// TODO
return undefined;
}
peek(): T | undefined {
// TODO
return undefined;
}
}
// Task 3
class Animal {
makeSound(): string {
return "...";
}
}
class Dog extends Animal {
// TODO: override makeSound()
}
// Task 4
function isString(value: unknown): value is string {
// TODO
return false;
}
const mixed: unknown[] = [1, "two", 3, "four"];
const strings = mixed.filter(isString);
console.log(strings);getArea() correctly returns the area for each shape, Dog's makeSound() returns "Woof", and the strings array contains "two" and "four".5-minute try it yourself
Use Task 2's Stack<T> class as a base class, and add a method isEmpty(): boolean that checks the length of the items array (5 minutes).
A quick word of caution
When writing a type guard function (value is string), don't leave the return type annotation as plain boolean — TypeScript only applies narrowing correctly when you write out the "value is Type" predicate precisely.