LearnCen Docs
Guides 4 min read v2

TypeScript Fundamentals

This guide will take you through the core concepts of TypeScript, building a strong foundation for any modern web or testing framework.

1. JavaScript vs. TypeScript

JavaScript (JS) is the scripting language of the web. It is "dynamically typed," meaning variables can hold any type of data, and errors are usually only caught when the code is actually running.

TypeScript (TS) is a "superset" of JavaScript developed by Microsoft.

  • Static Typing: You define the type of data (e.g., text, number) a variable should hold.
  • Compile-Time Errors: TypeScript catches errors before you run the code (during compilation).
  • Better Tooling: It provides excellent auto-completion and documentation directly in your code editor.

Ultimately, all TypeScript code is compiled (translated) back into plain JavaScript so the browser or Node.js can understand it.

2. ECMAScript (ECMA) Versions

JavaScript is based on a standard called ECMAScript. Every year, new features are added.

  • ES5 (2009): The older standard. Used var for variables.
  • ES6 / ES2015: A massive update. Introduced let, const, arrow functions, classes, and promises.
  • ES2016 - Present: Continuous smaller yearly updates (ES7, ES8, ESNext).

TypeScript allows you to write modern ESNext code, and it can automatically translate it down to older versions (like ES5) if you need to support very old browsers.

3. Variables and Types

In modern JavaScript/TypeScript, we use let for variables that can change, and const for variables that cannot change.

In TypeScript, we add Type Annotations using a colon :.

// Basic Types
let firstName: string = "Alice";
let age: number = 30;
let isDeveloper: boolean = true;

// Arrays
let skills: string[] = ["JavaScript", "TypeScript", "Playwright"];
let scores: number[] = [95, 88, 100];

// Any (Try to avoid this! It turns off TypeScript's checking)
let mysteriousVariable: any = "Could be text";
mysteriousVariable = 42; // Allowed because it's 'any'

// Constants (Cannot be reassigned)
const PI: number = 3.14159;

4. Functions

You can specify the types for a function's arguments (parameters) and the type of data it returns.

// Traditional Function
function greet(name: string): string {
    return "Hello, " + name;
}

// Arrow Function (Modern ES6 syntax)
const addNumbers = (a: number, b: number): number => {
    return a + b;
};

// Void (Function doesn't return anything)
function logMessage(message: string): void {
    console.log("Log: " + message);
}

5. Object-Oriented Programming (OOP)

TypeScript fully supports Object-Oriented Programming with Classes and Interfaces.

Interfaces

Interfaces define the "shape" of an object. It's a contract that says an object must have specific properties.

interface User {
    username: string;
    email: string;
    age?: number; // The '?' makes this property optional
}

const myUser: User = {
    username: "coder123",
    email: "coder@example.com"
};

Classes

Classes are blueprints for creating objects. TypeScript adds access modifiers like public (accessible anywhere) and private (accessible only inside the class).

class Car {
    // Properties
    public brand: string;
    private speed: number;

    // Constructor: Runs when you create a new Car
    constructor(brand: string) {
        this.brand = brand;
        this.speed = 0;
    }

    // Methods
    public accelerate(amount: number): void {
        this.speed += amount;
        console.log(`${this.brand} is going ${this.speed} mph.`);
    }
}

const myCar = new Car("Tesla");
myCar.accelerate(50);
// myCar.speed = 100; // Error! 'speed' is private.

6. Asynchronous Programming

JavaScript and TypeScript are "single-threaded," meaning they do one thing at a time. To handle tasks that take time (like fetching data from the internet), we use asynchronous programming.

Timeout

setTimeout runs code after a specified delay (in milliseconds).

console.log("1. Start");

setTimeout(() => {
    console.log("2. This runs after 2 seconds");
}, 2000);

console.log("3. End");
// Output order: Start -> End -> (2 seconds later) -> This runs after 2 seconds

Promises

A Promise is an object representing the eventual completion (or failure) of an asynchronous operation.

const orderPizza = new Promise<string>((resolve, reject) => {
    let pizzaArrived = true;

    if (pizzaArrived) {
        resolve("Pizza is here!"); // Success
    } else {
        reject("Pizza was dropped."); // Failure
    }
});

// Using the Promise
orderPizza
    .then((message) => console.log(message))
    .catch((error) => console.error(error));

Async and Await

async/await is a modern, cleaner way to write Promise-based code. It makes asynchronous code look synchronous (step-by-step).

// A function that returns a Promise
function fetchUserData(): Promise<string> {
    return new Promise((resolve) => {
        setTimeout(() => resolve("User data loaded"), 1500);
    });
}

// Using async/await
async function displayUser() {
    console.log("Fetching user...");

    // 'await' pauses the function until the Promise resolves
    const data = await fetchUserData(); 

    console.log(data);
}

displayUser();

7. Imports and Exports (Modules)

To keep code organized, you split it into multiple files called modules. You export things from one file and import them into another.

File: mathUtils.ts

// Export a function
export function multiply(a: number, b: number): number {
    return a * b;
}

// Default export (only one per file)
export default class Calculator {
    // ...
}

File: app.ts

// Import specific items using curly braces
import { multiply } from './mathUtils';

// Import default items
import Calculator from './mathUtils';

console.log(multiply(5, 5));