TypeScript

#11
TIOBE#37
PYPL#9
GitHub#6
RedMonk#6
IEEESpectrum#5
JetBrains#6
Programming LanguageStatic TypingJavaScriptWeb DevelopmentFrontendBackend

Programming Language

TypeScript

Overview

TypeScript is a programming language developed by Microsoft that adds static typing to JavaScript.

Details

TypeScript was developed by Microsoft in 2012 as a superset of JavaScript. JavaScript code works as TypeScript code as-is, while adding features like static type system, interfaces, generics, and decorators. TypeScript code is transpiled to JavaScript and runs on any JavaScript execution environment. It aims to improve type safety, development efficiency, and maintainability in large-scale application development, and is widely adopted in React, Angular, Vue.js, and Node.js projects.

Code Examples

Hello World

// Basic output
console.log("Hello, World!");

// Variable with type annotation
const message: string = "Hello, TypeScript!";
console.log(message);

// Function with type annotation
function greet(name: string): string {
    return `Hello, ${name}!`;
}

console.log(greet("TypeScript"));

Basic Type System

// Primitive types
let age: number = 25;
let name: string = "John";
let isActive: boolean = true;

// Arrays
let numbers: number[] = [1, 2, 3, 4, 5];
let fruits: Array<string> = ["apple", "banana", "orange"];

// Object type
let person: { name: string; age: number } = {
    name: "John Doe",
    age: 30
};

// Union types (allow multiple types)
let id: string | number = "abc123";
id = 123; // This is valid too

// Literal types
let status: "success" | "error" | "loading" = "success";

Interfaces

// Interface definition
interface User {
    id: number;
    name: string;
    email: string;
    age?: number; // Optional property
}

// Using interface
const user: User = {
    id: 1,
    name: "Jane Smith",
    email: "[email protected]"
};

// Interface inheritance
interface Admin extends User {
    role: string;
    permissions: string[];
}

const admin: Admin = {
    id: 2,
    name: "Administrator",
    email: "[email protected]",
    role: "administrator",
    permissions: ["read", "write", "delete"]
};

Function Typing

// Function type annotation
function add(a: number, b: number): number {
    return a + b;
}

// Arrow function type annotation
const multiply = (a: number, b: number): number => a * b;

// Function type variable
type MathOperation = (x: number, y: number) => number;

const divide: MathOperation = (a, b) => {
    if (b === 0) {
        throw new Error("Division by zero");
    }
    return a / b;
};

// Optional and default parameters
function createUser(name: string, age?: number, role: string = "user"): User {
    return {
        id: Math.random(),
        name,
        email: `${name.toLowerCase()}@example.com`,
        age
    };
}

Classes

// Class definition
class Vehicle {
    protected make: string;
    protected model: string;
    private _mileage: number = 0;

    constructor(make: string, model: string) {
        this.make = make;
        this.model = model;
    }

    // Getter
    get mileage(): number {
        return this._mileage;
    }

    // Method
    drive(distance: number): void {
        this._mileage += distance;
        console.log(`Drove ${distance}km. Total mileage: ${this._mileage}km`);
    }

    getInfo(): string {
        return `${this.make} ${this.model}`;
    }
}

// Inheritance
class Car extends Vehicle {
    private doors: number;

    constructor(make: string, model: string, doors: number) {
        super(make, model);
        this.doors = doors;
    }

    getInfo(): string {
        return `${super.getInfo()} (${this.doors} doors)`;
    }
}

const myCar = new Car("Toyota", "Prius", 4);
console.log(myCar.getInfo());

Generics

// Generic function
function identity<T>(arg: T): T {
    return arg;
}

const stringResult = identity<string>("hello");
const numberResult = identity<number>(42);

// Generic interface
interface Container<T> {
    value: T;
    getValue(): T;
}

class Box<T> implements Container<T> {
    constructor(public value: T) {}

    getValue(): T {
        return this.value;
    }
}

const stringBox = new Box<string>("TypeScript");
const numberBox = new Box<number>(123);

// Constrained generics
interface Lengthwise {
    length: number;
}

function logLength<T extends Lengthwise>(arg: T): T {
    console.log(`Length: ${arg.length}`);
    return arg;
}

logLength("string"); // OK
logLength([1, 2, 3]); // OK
// logLength(123); // Error: number doesn't have length property

Type Aliases and Type Guards

// Type aliases
type StringOrNumber = string | number;
type UserRole = "admin" | "user" | "guest";

// Type guards
function isString(value: StringOrNumber): value is string {
    return typeof value === "string";
}

function processValue(value: StringOrNumber): void {
    if (isString(value)) {
        // value is treated as string type here
        console.log(value.toUpperCase());
    } else {
        // value is treated as number type here
        console.log(value.toFixed(2));
    }
}

// Discriminated Union
interface Circle {
    kind: "circle";
    radius: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}

type Shape = Circle | Rectangle;

function calculateArea(shape: Shape): number {
    switch (shape.kind) {
        case "circle":
            return Math.PI * shape.radius ** 2;
        case "rectangle":
            return shape.width * shape.height;
        default:
            // Exhaustiveness checking
            const _exhaustiveCheck: never = shape;
            return _exhaustiveCheck;
    }
}

Decorators (Experimental Feature)

// Class decorator
function sealed(constructor: Function) {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
}

// Method decorator
function log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value;
    
    descriptor.value = function (...args: any[]) {
        console.log(`${propertyName} method was called`);
        return method.apply(this, args);
    };
}

@sealed
class ExampleClass {
    @log
    greet(name: string): string {
        return `Hello, ${name}!`;
    }
}

Versions

Version Release Date Major Features
TypeScript 5.5 2024-06 Inferred Type Predicates, Control Flow Narrowing
TypeScript 5.4 2024-03 NoInfer Utility Type, Object.groupBy support
TypeScript 5.3 2023-11 Import Attributes, Switch (true) Narrowing
TypeScript 5.2 2023-08 using Declarations and Explicit Resource Management
TypeScript 5.1 2023-06 Unrelated Types in Union, JSDoc @param and @returns
TypeScript 5.0 2023-03 Decorators, const Type Parameters
TypeScript 4.9 2022-11 satisfies Operator, Auto-Accessors

Reference Links

Official Documentation

Learning Resources

Development Tools