TypeScript is a superset of JavaScript: it adds types, but everything that runs in Node is still plain JavaScript. So before diving into types, it makes sense to have a solid grasp of the language itself: variables, values, functions, objects. Let's cover that minimum with examples.
Variables: let and const
In modern JavaScript, variables are declared with two keywords: const (the value cannot be reassigned) and let (it can). The old var is not used — it has confusing scoping rules.
const name = "Anna"; // cannot be reassigned
let count = 0; // count can be changed
count = count + 1; // ok
// name = "Bob"; // error: assignment to constant variable
Short rule: default to const, switch to let only when you actually need to reassign the variable.
Important: const prevents reassigning the variable itself, but does not prevent mutating the contents of an object or array it points to.
const user = { age: 20 };
user.age = 21; // ok: we're changing a field, not the variable user itself
Value types
In JavaScript, every value belongs to one of the primitive types. For starters, these are enough to know:
number— any number, integer or fractional (42,3.14). There is no separate type for integers.string— a string ("hello",'hi', or a template literal in backticks).boolean—trueorfalse.null— "intentionally no value".undefined— "value not set" (variable declared but nothing assigned; object field is absent).object— everything composite: objects, arrays, functions.
const total: number = 100;
const title = "Order"; // string
const isPaid = false; // boolean
let result; // undefined, nothing assigned yet
const missing = null; // intentionally empty
// template literal — interpolation via ${...}
const greeting = `Hello, ${title}!`;
The typeof operator tells you the type of a value at runtime:
typeof total; // "number"
typeof title; // "string"
typeof isPaid; // "boolean"
The practical difference between null and undefined: undefined usually appears on its own (forgot to assign, field is missing), while null is set by the developer to explicitly say "empty here".
Functions and arrow functions
A function is a block of code that takes arguments and returns a value. The classic function keyword:
function add(a, b) {
return a + b;
}
add(2, 3); // 5
More commonly you'll see the shorter arrow function. It's convenient for small operations and for passing into other functions:
const add = (a, b) => a + b; // single expression — return is implied
const square = (x) => x * x;
// multi-line body needs { } and an explicit return
const describe = (name) => {
const upper = name.toUpperCase();
return `Name: ${upper}`;
};
Arrows are especially handy when working with arrays, where a function is passed as an argument:
const nums = [1, 2, 3];
const doubled = nums.map((n) => n * 2); // [2, 4, 6]
Objects
An object is a collection of key-value pairs. It is the primary data-modelling structure in an application.
const order = {
id: 42,
customer: "Anna",
paid: false,
};
// accessing fields
order.id; // 42
order["customer"]; // "Anna" — same thing via string key
// adding and changing
order.paid = true;
order.total = 100; // new field
If a field is absent, accessing it returns undefined — this is not an error, just expected behaviour:
order.discount; // undefined: no such field
Arrays
An array is an ordered list of values. Zero-indexed.
const items = ["a", "b", "c"];
items[0]; // "a"
items.length; // 3
items.push("d"); // add to end → ["a", "b", "c", "d"]
The most common operations are iteration and transformation. Arrays have methods that accept a function:
const prices = [10, 20, 30];
prices.forEach((p) => console.log(p)); // just iterate
const withTax = prices.map((p) => p * 1.2); // transform each → new array
const big = prices.filter((p) => p >= 20); // keep matching ones → [20, 30]
const sum = prices.reduce((acc, p) => acc + p, 0); // fold into a single value → 60
map, filter, and reduce do not mutate the original array — they return a new result, which is convenient and predictable.
Destructuring
Destructuring is a short way to pull fields from an object or elements from an array into separate variables. You'll see it constantly: unpacking arguments, API responses, configs.
const user = { name: "Anna", age: 20, city: "Moscow" };
// instead of user.name and user.age
const { name, age } = user;
console.log(name, age); // "Anna" 20
// from an array — by position
const coords = [55.7, 37.6];
const [lat, lon] = coords;
console.log(lat, lon); // 55.7 37.6
Destructuring is often written directly in function parameters to extract the needed fields right away:
const formatUser = ({ name, city }) => `${name} from ${city}`;
formatUser(user); // "Anna from Moscow"
Comparison: == vs ===
JavaScript has two equality operators, and this is a frequent source of confusion.
==(loose) compares values by coercing types to match each other. This leads to surprising results.===(strict) compares without type coercion: values must match both in type and in content.
0 == "0"; // true — string was coerced to number
0 == false; // true — false was coerced to 0
"" == false; // true
0 === "0"; // false — different types
0 === false; // false
Short rule: always use === and !==. The type coercion in == almost never does what you expect, and it hides bugs. TypeScript will confirm the same rule later.
A separate note on checking "is there a value or not". Comparing with null via == intentionally treats null and undefined as equal:
let value; // undefined
value == null; // true — catches both null and undefined
value === null; // false — this is undefined, not null
In short
constby default,letonly for reassignment; don't usevar.- Primitive types:
number,string,boolean,null,undefined,object. Check the type of a value withtypeof. undefined— "not set" (appears on its own),null— "empty" (the developer sets it explicitly).- Functions are written with
functionor more concisely as arrow functions(...) => ...; arrows are convenient to pass tomap/filter/reduce. - Objects are key-value pairs, arrays are ordered lists;
map/filter/reducereturn a new result without mutating the original. - Destructuring concisely extracts object fields and array elements, including directly in function parameters.
- Always compare with
===/!==—==coerces types and hides bugs.
What to read next
- TypeScript basic types — how to add types on top of this foundation and catch errors before running.
- JavaScript in Depth — a series on the language core: closures, prototypes, coercion, promises from the inside.
- Async and the event loop — Promise, async/await and how Node executes code.
- Modules and npm — import/export and adding dependencies.