TypeScript

Begin by installing one project-local compiler and tracing a tiny TypeScript source file through checking, emitted JavaScript, and Node execution. Then build precise domain models, narrow unknown values, preserve relationships with generics, validate browser and server boundaries, test static and runtime claims separately, migrate JavaScript deliberately, and deliver one complete typed platform.

Course details and reading size
Tutorial
Reading comfortAdjust lesson text without changing code or interface size.

TypeScript’s role and the compiler workflow

Objective Install one project-local compiler, check and emit one complete program, run its JavaScript, and distinguish every stage and failure.

Core explanation

TypeScript is a language and static checker built on JavaScript; a .ts source file is plain text that may contain JavaScript plus type syntax. The compiler reads a project configuration, parses the selected source, reports diagnostics for inconsistent static relationships, and can emit ordinary JavaScript for a runtime to execute. Static analysis happens before the emitted program runs: an annotation such as `course: string` is a checked claim, while inference derives a type such as number from the value 20. Types are normally erased, so Node executes JavaScript rather than an annotation. Inside a disposable `typescript-first` directory, verify Node and npm, then run `npm init --yes` and `npm install --save-dev typescript`. This network-dependent install updates package.json and package-lock.json; inspect both, retain the lock, and do not use a hidden global compiler. Verify the exact local compiler with `node node_modules/typescript/bin/tsc --version`, then save the complete tsconfig.json and src/index.ts shown here. Run the local compiler with `--project tsconfig.json --noEmit` to check without output, then run it without `--noEmit` to create dist/index.js. Inspect that emitted file and execute `node dist/index.js`. A successful check proves selected source relationships under this compiler and configuration; the runtime command proves the emitted program’s observed behavior. Later chapters add browser libraries, Node declarations, packages, tests, and production builds only when each boundary is taught. Compiler configuration and static success remain feedback rather than a security boundary, so align emission with the real runtime and keep malformed data, races, authorization, artifact inspection, and source maps in their own evidence plan.

Keep installation, project selection, static checking, JavaScript emission, and runtime execution as five visible stages with separate evidence.

Create one disposable project with one known local compiler

Begin from the completed JavaScript course rather than pretending TypeScript is a first programming language. Reuse the safe terminal, verified Node.js and npm commands, package and lockfile model, modules, tests, and browser-versus-Node distinction already learned there. Create a new disposable directory named typescript-first and inspect that exact path before installing anything. Run `node --version` and `npm --version` and record the outputs. If either command is missing, return to the JavaScript runtime setup instead of copying later commands blindly.

Run `npm init --yes`, inspect the new package.json, and then run `npm install --save-dev typescript`. A package is a versioned unit of code, a development dependency is needed to build or check the project rather than by the delivered program, and package-lock.json records the resolved dependency graph. node_modules contains the installed local files and is generated rather than handwritten. Verify the owned compiler with `node node_modules/typescript/bin/tsc --version`. This explicit path cannot silently fall back to an editor extension or unrelated global tsc. Record the network-dependent install command, compiler version, package files, directory, and any failure before continuing.

Define the selected program before asking the checker a question

A TypeScript project is the set of source files and options selected by tsconfig.json. The shown `include` pattern selects .ts files under src. rootDir says where authored source begins and outDir says where emitted JavaScript belongs. target selects the JavaScript syntax generation, module selects the module form, strict enables a family of stronger relationship checks, and noEmitOnError refuses fresh output while diagnostics remain. These options do not install a runtime or make external data trustworthy. Save the complete JSON exactly as tsconfig.json in the project root and the TypeScript region as src/index.ts.

A type describes values the checker permits at one program point. The `: string` after course is a type annotation: it states an intended relationship and is not a runtime conversion. The lessons binding has no annotation; the compiler infers number from the initializer 20. A diagnostic is a compiler report that the selected source and configuration cannot satisfy one relationship. Read its filename, line, code, and message before editing. An editor hint may help, but the recorded project-local command is the shared evidence because it names the compiler and tsconfig rather than relying on one person’s private setup.

Keep checking, emission, inspection, and execution separate

Run `node node_modules/typescript/bin/tsc --project tsconfig.json --noEmit`. The explicit project option selects tsconfig.json, and --noEmit asks only for static analysis. A command that prints no diagnostic and returns success means the selected program satisfied the configured static rules; it does not mean JavaScript ran. Next run the same command without --noEmit. Inspect dist/index.js before executing it. The string and number values plus console call remain, but the `: string` annotation is absent because ordinary TypeScript type syntax is erased during emission.

Run `node dist/index.js` only after the current build succeeds and verify the exact sentence. Node supplies the runtime console and executes the emitted JavaScript. This observation proves that these emitted bytes produced this result in the recorded Node runtime. It does not prove an API response, storage record, user input, authorization decision, browser DOM, or future dependency is safe. Those values do not exist for the compiler to inspect. Later chapters begin external inputs as unknown, validate them at runtime, and construct trusted domain values only after evidence.

Change one relationship and refuse stale evidence

Change only the lessons declaration to `const lessons: number = "20";`. Predict that the source still contains text that JavaScript could concatenate, but the declared number relationship is false. Run only the check command and locate the diagnostic that string is not assignable to number. Because a prior dist/index.js may still exist, executing it would demonstrate old emitted bytes rather than the failed current source. noEmitOnError prevents a fresh candidate; it cannot make an older output truthful. Label source identity, compiler result, emitted-file identity, and runtime result separately.

Restore the numeric 20, rerun the check, build, inspect, and execute. Then copy the project without node_modules and give it with the lockfile and written commands to another learner. They run the declared install, verify the local compiler, reproduce the baseline, introduce a different annotation mismatch, repair it, and explain all five stages without an editor extension or global package. Stop if dependency installation cannot be reproduced rather than substituting hidden machine state. The first chapter is complete when another person can distinguish which tool selected, checked, emitted, and ran which artifact.

CURRICULUM CONTEXTRelated courses and the course concept model