← back to section

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).
  • booleantrue or false.
  • 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

  • const by default, let only for reassignment; don't use var.
  • Primitive types: number, string, boolean, null, undefined, object. Check the type of a value with typeof.
  • undefined — "not set" (appears on its own), null — "empty" (the developer sets it explicitly).
  • Functions are written with function or more concisely as arrow functions (...) => ...; arrows are convenient to pass to map/filter/reduce.
  • Objects are key-value pairs, arrays are ordered lists; map/filter/reduce return 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.
  • 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.