Come Back Later: Review Challenges

The Course
•
4 min read

Return after two or three days. Try these challenges without reading old solutions first. Retrieval after a delay helps reveal which ideas you can use independently. Spend about twenty minutes, then revisit the relevant lesson for any gap.

Challenge 1 — lookup: implement a generic first helper for a readonly list. It must preserve the element type and allow an empty list. Demonstrate a safe caller for both strings and numbers.

Challenge 2 — boundary: write a guard for a finite nonnegative integer from unknown. Include zero, NaN, Infinity, negative numbers and numeric text in your tests. Explain why typeof alone is insufficient.

Challenge 3 — update: write a helper that appends a topic to a readonly string list by creating a new list. Show that the original is unchanged. Explain why readonly is not Object.freeze.

Finally, explain three distinctions in plain language: checking versus execution; a type assertion versus runtime validation; and a clean compiler result versus evidence that the program implements its intended behavior. If you can only repeat definitions, find a concrete example from your own exercise.

The example below deliberately contains a logic mistake that passes checking. The optional diagnostic lab contains a type mistake. Compare the evidence needed to find each.

Predict, check, then run

Before running, write down the output and explain which information the checker knows. Click Check types first, then Check & run.

Predict, then runTypeScript
function remaining(pages: number, read: number): number {
  return pages + read;
}

console.log(remaining(100, 40));

Enable JavaScript to edit and type-check this example.

Check your prediction
140

Read a real compiler error

Identify the unsafe assumption before checking. Then explain why a runtime test and a type check give different evidence from the arithmetic example above.

Find and fix the type errorTypeScript
const first: string | undefined = undefined;

console.log(first.toUpperCase());

Enable JavaScript to edit and type-check this example.

Check your diagnosis

The first value may be absent. Add a real branch or optional chaining with an intentional fallback. Do not append ! to make the diagnostic disappear.

Your turn

Exercise

Come Back Later: Review Challenges: practise

Complete the three review challenges above. Print TYPES for the first string, 0 for a missing first number using a fallback, true for a valid zero, false for numeric text, Types for the original list and Types,Review for the copied list.

Your workspaceTypeScript
// Attempt all three helpers from memory. Keep unknown data guarded.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

Use a type parameter for the relationship, conditions for evidence, and a copy for the update.

Hint 2: a first step

First write each function’s input and return annotation; then implement the JavaScript operation.

Show one solution
One possible solutionTypeScript
function first<T>(items: readonly T[]): T | undefined {
  return items[0];
}

function isCount(value: unknown): value is number {
  return (
    typeof value === "number" &&
    Number.isFinite(value) &&
    Number.isInteger(value) &&
    value >= 0
  );
}

function addTopic(topics: readonly string[], topic: string): string[] {
  return [...topics, topic];
}

console.log(first(["Types"])?.toUpperCase() ?? "Empty");
console.log(first<number>([]) ?? 0);
console.log(isCount(0));
console.log(isCount("0"));

const original = ["Types"];

console.log(original.join(","));
console.log(addTopic(original, "Review").join(","));

Enable JavaScript to edit and type-check this example.

TYPES
0
true
false
Types
Types,Review

Explain the types at the function boundary and the runtime checks, if any. Compare your approach before copying this answer.

Change it and explain it

Fix remaining to subtract and write a regression assertion. If any challenge required the solution, retry it next week with a different domain. Continue with intermediate JavaScript for modules and asynchronous applications; advanced JavaScript and further TypeScript levels can build on this foundation later.

Was this article helpful?

Your response is saved on this device.