Build a small public operation that consumes a readonly title and returns trimmed text without mutation. Its compile contract rejects a numeric title. Its runtime contract preserves the source and actually trims the output.
Include a positive call, one focused negative caller and a behavioral assertion. Then perform two different mutations. Widening title to string|number should break the negative test. Removing trim should leave the caller types valid but fail runtime evidence.
This is the same two-layer strategy used by the final gateway. Twenty minutes spent proving a test fails for the right reason is more useful than adding an unused abstraction. Keep all intentional invalid calls out of runtime execution.
Predict, check, and run
Write the output before running. Use Check types first, then Check & run. Types disappear at runtime: explain both what the compiler checks and what the code actually does. Each editor is an independent ES module; await asynchronous work explicitly.
const source = { title: " Types " };
const before = source.title;
console.log(source.title.trim());
console.log(source.title === before);Enable JavaScript to edit and type-check this example.
Check your prediction
Types
true Acceptance cases before you code
Write a small test plan before implementing two independent regression layers. These cases extend the brief; they are not a second worked solution. Predict the expected behavior independently, then test through the public function. A good ordinary example and a good boundary example should catch different possible mistakes.
| Case to try | What your result should demonstrate |
|---|---|
| Valid padded title | Runtime output is trimmed without source mutation |
| Numeric-title caller | Negative compile test is required |
| Remove trim or weaken title type | Different test layers expose the two defects |
After the core task passes, deliberately break one rule and identify the case that notices it. Restore the implementation and explain the failure in terms of the contract, not the number of assertions. If a case requires a concept you have not recalled, revisit the relevant lesson before opening the solution.
Build it yourself
Checkpoint: Regression Evidence: practise
Write label(book:{readonly title:string}):string. Add a never-called negative caller passing title:25 under @ts-expect-error. Assert a padded title is trimmed and the source unchanged, then print both layers verified.
// Start from the stated contract. Add a valid call and an edge case.Enable JavaScript to edit and type-check this example.
Hint 1: the idea
The negative caller should test only the title parameter type.
Hint 2: a first step
Keep the runtime assertion outside any catch that could swallow its failure.
Show one solution
function label(book: { readonly title: string }): string {
return book.title.trim();
}
function negativeContracts(): void {
// @ts-expect-error numeric title is not the public contract
label({ title: 25 });
}
const source = { title: " Types " };
if (label(source) !== "Types" || source.title !== " Types ") {
throw new Error("Runtime contract failed");
}
console.log("both layers verified");Enable JavaScript to edit and type-check this example.
both layers verifiedTrace the implementation against the task before comparing styles. A passing example supports that case; use the changes below to challenge the wider contract.
Change it and test it
For the type mutation, widen the input and return String(book.title).trim() so there is no unrelated implementation error. The unused directive must still fail. Separately remove trim and verify the runtime assertion catches it.
Completion is saved in this browser only. It does not measure mastery.