A type check verifies that your code uses its declared contracts consistently. A runtime test verifies an observable behavior for a chosen input. Your project needs both. A calculation can return the wrong number with no compiler diagnostic, and a parser can claim a shape without checking it properly.
A tiny assertion helper can compare an actual primitive value with an expected one and throw Error when they differ. A failed assertion is a runtime failure, separate from compiler errors. Include a label so the failing case is easy to locate.
For the planner, test a normal mixed list, an empty list, a completed zero-minute session, and an all-incomplete list. For the parser, test syntax errors, non-list JSON, every missing field, wrong field types, blank text and negative minutes. A few chosen boundaries provide better evidence than many copies of the same happy path.
Mutation checking is a useful self-review habit: temporarily remove a validation condition or count incomplete rows too. At least one existing test should fail. If every test still passes, add a case that distinguishes correct and broken behavior. Then restore the implementation.
The downloadable project’s tests use Node’s built-in test runner and strict assertions on the emitted JavaScript. The code below uses a small self-contained helper so it also runs in the browser editor. Both approaches test behavior; neither replaces the compiler.
Predict, check, then run
Before running, write down the output and explain which information the checker knows. Click Check types first, then Check & run.
function assertEqual(actual: number, expected: number, label: string): void {
if (actual !== expected) {
throw new Error(`${label}: expected ${expected}, got ${actual}`);
}
}
function total(minutes: readonly number[]): number {
let result = 0;
for (const value of minutes) {
result += value;
}
return result;
}
assertEqual(total([10, 20]), 30, "two sessions");
assertEqual(total([]), 0, "empty");
console.log("2 tests passed");Enable JavaScript to edit and type-check this example.
Check your prediction
2 tests passed Separate caller evidence from runtime evidence
A diagnostic can prove a particular caller is rejected, but not that a decoder trims text or a report sums only completed minutes. Runtime success cannot maintain the whole public type surface either. Read positive assertions as well as rejection cases; a parser rejecting every input should not pass a useful suite.
| Boundary or case | What to inspect |
|---|---|
| Wrong caller field type | Compiler rejects it before execution |
| Malformed imported value | Runtime validation rejects external data |
| Wrong arithmetic | Expected values distinguish record count from minutes |
Remove one runtime predicate without changing its signature and identify the behavior test that fails. Then weaken a public type and identify the contract test that fails. Restore each change and explain why the other layer cannot replace that evidence.
Your turn
Type Checks & Runtime Tests: practise
Write completedMinutes for readonly records containing minutes:number and done:boolean. Add runtime assertions for mixed rows, an empty list and a completed zero-minute row. Print 3 tests passed only after the assertions finish.
// Define the function and a small numeric assertion helper.Enable JavaScript to edit and type-check this example.
Hint 1: the idea
Choose cases that would catch accidentally counting incomplete rows.
Hint 2: a first step
Use a mixed case with different completed and incomplete minute values.
Show one solution
type Session = {
minutes: number;
done: boolean;
};
function completedMinutes(sessions: readonly Session[]): number {
let total = 0;
for (const session of sessions)
if (session.done) {
total += session.minutes;
}
return total;
}
function assertEqual(actual: number, expected: number, label: string): void {
if (actual !== expected) {
throw new Error(`${label}: expected ${expected}, got ${actual}`);
}
}
assertEqual(
completedMinutes([
{ minutes: 25, done: true },
{ minutes: 40, done: false }
]),
25,
"mixed"
);
assertEqual(completedMinutes([]), 0, "empty");
assertEqual(completedMinutes([{ minutes: 0, done: true }]), 0, "zero");
console.log("3 tests passed");Enable JavaScript to edit and type-check this example.
3 tests passedExplain the types at the function boundary and the runtime checks, if any. Compare your approach before copying this answer.
Change it and explain it
Remove the done condition temporarily. Check types still succeeds, but the mixed test should fail. Restore it. For the parser, name a specific test that would catch removing the nonblank-topic check. Write down what evidence a passing suite still cannot provide about every possible input.
Completion is saved in this browser only. It does not measure mastery.