PART 1: TypeScript
Chapter 1: Getting Started with TypeScript
JavaScript (the precursor to TypeScript) started life in the browser as a light scripting language that worked inside tiny windows of time. It handled button clicks, page effects, and simple logic. The early web needed something quick and flexible, so JavaScript arrived, small and nimble, ready to run anywhere a browser existed.
Over the years that small language became the backbone of enormous applications. It shifted from sprinkling effects across pages to driving whole interfaces, handling networking, storing data, and powering collaborative tools. This expansion created new pressure. Teams needed stronger tools around structure and meaning. They needed a way to describe their intentions so editors and build systems could help. These needs shaped the world into which TypeScript stepped.
Although JavaScript still runs the web and sits inside every TypeScript file you compile, the modern developer works in a landscape where clarity and safety matter. This chapter opens the door to that world. It explains why TypeScript exists, how to install the tools, how to shape a project, and how to run your first program. Everything else grows from these first steps.
Why TypeScript exists and when to use it
TypeScript grew from a simple idea. JavaScript needed stronger footing for large projects, so TypeScript added a type system that could guide the shape of data and the intent of functions. This change helped developers catch problems early and encouraged designs that felt tidy rather than tangled. TypeScript also introduced modern language features that arrived before they landed in JavaScript itself, giving teams a smoother path toward reliable codebases.
The language is most useful when projects grow bigger than a single file or when several people share the same code. It helps when APIs must stay predictable and when refactoring should feel like shifting a puzzle piece rather than pulling out a wire from a crowded circuit. TypeScript also shines when you want clarity inside editor tooling. Features such as autocomplete, parameter hints, and inline documentation become far more helpful once types begin shaping the world around them.
Although TypeScript transforms into JavaScript before running, most developers treat it as its own language. This approach gives the reader a clean start and avoids the usual pattern where TypeScript is taught as an afterthought. In practice, developers pick up TypeScript first and meet JavaScript naturally as the compiled output. This book follows that pattern.
Installing Node, npm, and the TypeScript compiler
TypeScript needs a runtime that understands the compiled JavaScript it produces. Node provides that environment. Installing Node also installs npm (The Node Package Manager) so you can fetch packages, manage dependencies, and install the TypeScript compiler. The goal in this section is to create a steady foundation before you write any code.
Most systems use the official installers from the Node website (nodejs.org/en/download). These installers place Node and npm in your system path so you can use them from any terminal. After installation you can confirm everything is ready by asking for version numbers.
node --version
npm --version
Once Node is working, you can install TypeScript globally or within a project folder. Global installation makes the tsc command available everywhere.
npm install -g typescript
You can confirm that the TypeScript compiler works by checking its version.
tsc --version
npm about new patch versions or minor fixes. These updates are usually safe to install because they contain improvements that smooth out small issues. Accepting them keeps your tools steady and avoids problems that older versions sometimes create.
At this point the tools are in place. You have a runtime, a package manager, and a compiler ready to translate your TypeScript into clean JavaScript.
Project layout and first tsconfig.json
A TypeScript project grows smoother when the folder structure is simple. Most developers create a root directory with two main parts: a src folder that holds the TypeScript files and an out or dist folder that holds the compiled JavaScript. The TypeScript compiler can produce that second folder automatically once you set up the configuration file:
my-project
├── src
│ ├── main.ts
│ └── …
├── dist
│ └── (compiled files appear here after running tsc)
├── package.json
└── tsconfig.json
The tsconfig.json file tells the compiler what rules to follow. It describes the language level, the strictness settings, the output folder, and any features you want enabled. Start with a small version and expand later once the project grows.
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"outDir": "dist",
"strict": true
},
"include": ["src/…"]
}
This configuration keeps the project predictable. The strict option gives you clearer boundaries, the target setting controls the JavaScript flavor, and the outDir separates clean output from edited source files.
tsconfig.json acts like a contract between your code and the compiler. It keeps expectations clear as the project grows.
Once the configuration file exists, the project begins to feel like a real workspace. You can add TypeScript files to the src folder and trust that the compiler will take care of the rest.
Compiling and running a simple program
Now you can create your first real TypeScript file. The file can be as small as a few lines, but even this short example shows the full pipeline from TypeScript to JavaScript to the Node runtime. Create a file named src/main.ts and add a simple greeting.
const message = "Hello TypeScript";
console.log(message);
Next you tell the compiler to translate the file. The compiler reads the configuration, scans the src folder, and drops compiled JavaScript into the output directory.
tsc
You should now see a dist folder containing main.js. This file is pure JavaScript so Node can run it without any additional support.
node dist/main.js
This small loop shows the entire workflow. You write TypeScript, the compiler produces JavaScript, and Node runs the result. Everything else in the language builds on this pattern.