TypeScript is JavaScript with a type system added on top. You describe what data your code expects (a string, a number, an object of a certain shape), and the compiler checks the program before it runs, highlighting errors right in the editor. Today most new React, Vue, Angular and Node.js projects are written in TypeScript, and knowing it is a standard requirement in job listings.
The problem: JavaScript finds out about errors too late
JavaScript is a dynamically typed language: the type of a value is only known at runtime. Broken code crashes only when execution reaches the faulty line — sometimes already in front of a user. Three typical bugs:
// cart.js — plain JavaScript
const user = { name: "Aysel", email: "aysel@example.com" };
console.log(user.emial.toLowerCase()); // typo in the property name
const users = [{ id: 1, name: "Murad" }];
const found = users.find((u) => u.id === 2);
console.log(found.name); // there is no user with id 2 — found is undefined
function formatPrice(amount) {
return amount.toFixed(2) + " AZN";
}
formatPrice("15"); // passed a string instead of a numberThe editor sees nothing wrong here. Let's run node cart.js:
TypeError: Cannot read properties of undefined (reading 'toLowerCase')The program stopped at the first error; the other two will only show up on later runs (reading 'name', then amount.toFixed is not a function). If a line runs rarely, the bug can live in the code for months.
The same code in TypeScript
TypeScript adds static typing: types are checked before the program runs, based on the source text. Let's specify the user type and the parameter type:
type User = { name: string; email: string };
const user: User = { name: "Aysel", email: "aysel@example.com" };
console.log(user.emial.toLowerCase()); // ❌ error in the editor
const users: User[] = [{ name: "Murad", email: "murad@example.com" }];
const found = users.find((u) => u.name === "Leyla");
console.log(found.name); // ❌ error in the editor
function formatPrice(amount: number): string {
return amount.toFixed(2) + " AZN";
}
formatPrice("15"); // ❌ error in the editorAll three problems are underlined in red while you type. The compiler reports:
error TS2551: Property 'emial' does not exist on type 'User'. Did you mean 'email'?
error TS18048: 'found' is possibly 'undefined'.
error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.TS knows every property of the User type and suggests the correct name; it remembers that find may return undefined and requires you to handle that; it sees that the function expects a number but receives a string.
TypeScript is a superset of JavaScript
TypeScript is a superset of JavaScript: any valid JS code is also syntactically valid TS. TS only adds type annotations (: string), type and interface declarations and the like, so you can migrate gradually.
Browsers and Node.js execute only JavaScript, so TS code is turned into JS before it runs. In the process types are erased — nothing of them remains in the output:
// price.ts — source code
type Product = { title: string; price: number };
function withTax(product: Product): number {
return product.price * 1.18;
}
console.log(withTax({ title: "Keyboard", price: 45 }));// price.js — compiler output
"use strict";
function withTax(product) {
return product.price * 1.18;
}
console.log(withTax({ title: "Keyboard", price: 45 }));The Product type and the annotations are gone; the logic is unchanged. The consequence: types do not exist at runtime, and TS cannot check data coming from outside — a server response, JSON.parse, user input:
type User = { name: string; age: number };
const data: User = JSON.parse('{"name": "Leyla"}'); // TS takes our word for it
console.log(data.age.toFixed(0));
// → TypeError: Cannot read properties of undefined (reading 'toFixed')JSON.parse returns a value without any checks, and TS believes it is a User. At such boundaries you need a runtime check — in this course we do that with the Zod library.
💡 Since types are erased, TypeScript neither slows down nor speeds up your program: the same JavaScript runs at runtime. All the benefit is at development time.
The main benefit for teams: hints and safe refactoring
The editor knows the shape of every value: after user. it lists the properties, in a function call it shows the parameters, and on hover it shows the type. A function signature becomes documentation that never goes stale:
type Order = { id: number; total: number; status: "new" | "paid" | "shipped" };
function updateStatus(order: Order, status: Order["status"]): Order {
return { ...order, status };
}
const order: Order = { id: 1, total: 120, status: "new" };
updateStatus(order, "payed");
// ❌ Argument of type '"payed"' is not assignable to parameter of type '"new" | "paid" | "shipped"'.The signature shows which statuses are allowed, and TS will not let the "payed" typo through. The second benefit is safe refactoring. Let's rename price to amount in the type:
type Product = { title: string; amount: number }; // used to be price
function cartTotal(items: Product[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
// ❌ Property 'price' does not exist on type 'Product'.
}TypeScript immediately shows every broken place in the project. In JS you would have to find them with a text search and hope nothing was missed — in a project with hundreds of files that is a huge difference.
Where TypeScript is used today
| Platform | How TS is used there |
|---|---|
| React | the Vite react-ts template; Next.js creates TS projects by default |
| Vue 3 | the framework itself is written in TS, components use <script setup lang="ts"> |
| Angular | TypeScript is mandatory, there is no other option |
| Node.js | Express, NestJS; since version 22 Node runs .ts files directly |
| Deno, Bun | run TypeScript out of the box, with no setup |
About versions: the 5.x line (2023–2025) is found in many production projects. TypeScript 6.0 (2026) is the last compiler written in TypeScript itself; it is a transitional release that changes a number of default settings. TypeScript 7 is the compiler rewritten in Go: it checks projects roughly 10 times faster. The language has not changed: the code in this course works in both 5.x and 7.
Common mistakes
1. Believing TS checks data while the program runs. An API response or the contents of localStorage may not match the type: a : User annotation guarantees nothing by itself.
2. Turning checks off with any. The any type means "no need to check", and TS goes quiet:
const user: any = { name: "Aysel" };
user.emial.toLowerCase(); // TS is silent — a TypeError again at runtime
const safeUser: { name: string } = { name: "Aysel" };
safeUser.emial; // ❌ Property 'emial' does not exist on type '{ name: string; }'.3. Ignoring the red underlines "since it runs anyway". By default JavaScript is emitted even when there are type errors, but a type error almost always means a real bug.
4. Rewriting the project from scratch. Projects are migrated gradually: files are renamed to .ts, and types are added where they help most.
Summary
- TypeScript is JavaScript plus static types; errors are visible in the editor before running.
- It catches property typos, access to a possibly
undefinedvalue, wrong arguments and much more. - TS is a superset of JS: any JS code is valid, so you can migrate gradually.
- Types are erased during compilation; they do not exist at runtime, so external data must be checked separately.
- The main team benefit is autocompletion, types as documentation and safe refactoring.
- TS is used in React, Vue, Angular, Node.js, Deno and Bun; the current version is TypeScript 7 with a Go-based compiler.
Practice
- Find all the errors TypeScript would catch in this code and explain each one:
const city = { name: "Baku", population: 2300000 }; console.log(city.populaton); const n = Math.round("3.7");. - Open the TypeScript Playground, paste the example from "The same code in TypeScript" and fix the code so that no errors remain.
- In the Playground, describe a
Studenttype with the fieldsname,groupandscores(an array of numbers) and a functionaverage(student: Student): number. Renamescorestogradesand see which places TS highlights. - Move a small function from one of your JS projects (a cart total, filtering a list) into the Playground and add types. Check that a call with wrong data is highlighted.
💡 In exercise 4, don't try to describe everything at once: start with the function parameters — that gives the most benefit.