Use Node.js 22+ and npm. Extract the catalogue ZIP and open a terminal inside catalogue. Run npm install once, then npm run check, npm start and npm test. Start prints Types. Checking uses TypeScript 5.9.3, the same version as the browser course.
Read the imports directly: service.ts imports domain.ts; main.ts imports both service.ts and domain.ts. Domain exports runtime functions and types, service imports the decoder as a value and Book/Result as types, and main invokes the configured loader. Ordinary imports and import type have different runtime meaning, as taught on Day 1.
The compiler uses strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes and noEmitOnError. NodeNext resolves .js imports to .ts source and emits .js modules for Node. Keep generated dist and installed node_modules out of authored source.
The browser example combines the same definitions into one module because it does not resolve local project files. Do not “fix” a project import by deleting its .js extension without understanding the target environment. TypeScript configuration changes should be deliberate and checked alongside runtime execution.
Predict, run, and explain
Write the output and trace the important state changes before checking it. Then run the program. Use Check types first; execution is allowed only when the real compiler accepts the source.
const stages: readonly [string, string, string] = ["domain", "service", "main"];
console.log(stages.join(" -> "));Enable JavaScript to edit and type-check this example.
Check your prediction
domain -> service -> main Trace commands and modules rather than directory order
The compiler checks source dependencies and emits JavaScript; Node runs the emitted main entry. Domain owns validation and state rules, service owns the injected transport adapter, and main supplies orchestration. File listing order is not an execution plan. Follow the actual imports and function calls.
Compile-only contracts deliberately contain misuse and must not run as the application. Keep their checks separate from the behavior suite, which exercises normalized data, failures and schedules through emitted code.
| Boundary or case | What to inspect |
|---|---|
| Check | Verify source and focused negative contracts |
| Start | Run emitted main with the deterministic transport fixture |
| Test | Check types and then validation, transitions and controlled schedules |
Change only a transport fixture and predict valid, invalid-data and rejection results. Then inspect emitted imports: runtime decoder imports remain while type imports disappear. Recheck both checking and execution after changing module settings.
Your turn
Modules & Compiler Settings: practise
Write a typed dependency record with domain, service and main string descriptions. Print validation, loading and orchestration respectively. Then find those responsibilities in the actual files rather than adding them all to one function.
// Use a small explicit record type and clear responsibilities.Enable JavaScript to edit and type-check this example.
Hint 1: the idea
File boundaries should reflect behavior, not arbitrary line counts.
Hint 2: a first step
Assign one responsibility to each named stage.
Show one solution
type Responsibilities = {
domain: string;
service: string;
main: string;
};
const responsibilities: Responsibilities = {
domain: "validation",
service: "loading",
main: "orchestration"
};
console.log(responsibilities.domain);
console.log(responsibilities.service);
console.log(responsibilities.main);Enable JavaScript to edit and type-check this example.
validation
loading
orchestrationExplain why the implementation meets the stated contract. Which part is enforced by the language or checker, and which part needs behavioral evidence?
Change it and test it
Run the download locally if possible and inspect the emitted service.js: its import type statements should be absent while its decoder import remains. Keep compile-only negative tests out of runtime entry points. Explain which settings make this project stricter than merely stripping type annotations.
Completion is saved in this browser only. It does not measure mastery.