Skip to content

Latest commit

 

History

History
470 lines (391 loc) · 8.72 KB

File metadata and controls

470 lines (391 loc) · 8.72 KB

TypeScript

Declare a variable

let variableName: dataType;

Initialize a variable

let count: number = 10;

Declare a constant

const PI: number = 3.14159265359;

Type annotations for functions

function greet(name: string): string {
    return `Hello, ${name}!`;
}

Optional functions parameters

function printMessage(message: string, prefix?: string) {
    if (prefix) {
        console.log(`${prefix}: ${message}`);
    } else {
        console.log(message);
    }
}

Default function parameters

function greet(name: string, greeting: string = "Hello") {
    console.log(`${greeting}, ${name}!`);
}

Arrow function (Lambda expression)

const add = (a: number, b: number): number => a + b;

Interface

interface Person {
    name: string;
    age: number;
}

Class Declaration

class Car {
    make: string;
    constructor(make: string) {
        this.make = make;
    }
}

Class inheritance

class SportsCar extends Car {
    topSpeed: number;
    constructor(make: string, topSpeed: number) {
        super(make);
        this.topSpeed = topSpeed;
    }
}

Access modifiers in classes

class Animal {
    private name: string;
    constructor(name: string) {
        this.name = name;
    }
}

Abstract classes

abstract class Shape {
    abstract area(): number;
}

Type Aliases

type Point = { x: number; y: number };

Union Types

let result: string | number;
result = "success";
result = 42;

Type assertion (type casting)

let value: any = "Hello, TypeScript!";
let length: number = (value as string).length;

Generics

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

Enums

enum Color {
    Red,
    Green,
    Blue,
}

Array iteration with forEach

const numbers: number[] = [1, 2, 3, 4, 5];
numbers.forEach((num) => console.log(num));

Array mappping

const doubled = numbers.map((num) => num * 2);

Array filtering

const evenNumbers = numbers.filter((num) => num % 2 === 0);

Object destructuring

const { name, age } = person;

Spread operator

const parts = [1, 2, 3];
const whole = [...parts, 4, 5];

Rest parameters

function sum(...nums: number[]): number {
    return nums.reduce((total, num) => total + num, 0);
}

Promises

const fetchData = (): Promise<Data> => {
    return fetch("https://example.com/data")
        .then((response) => response.json())
        .catch((error) => {
            throw new Error("Error fetching data");
        });
};

Async/Await

async function fetchData(): Promise<Data> {
    try {
        const response = await fetch("https://example.com/data");
        return await response.json();
    } catch (error) {
        throw new Error("Error fetching data");
    }
}

Type guards for instanceof

if (myVar instanceof MyClass) {
    // myVar is an instance of MyClass
}

Type guards for typeof

if (typeof myVar === "string") {
    // myVar is a string
}

Type guards for custom types

function isPerson(obj: any): obj is Person {
    return "name" in obj && "age" in obj;
}

Nullish coallescing operator

const result = value ?? defaultValue;

Optional chaining

const city = user?.address?.city;

Non-Nullable assertion operator

let element: HTMLElement | null = document.getElementById("example")!;

Decorators

function log(target: Object, key: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
        console.log(`Calling ${key.toString()} with arguments: ${args.join(", ")}`);
        return originalMethod.apply(this, args);
    };
}

Type inference with as const

const config = {
    API_URL: "https://api.example.com",
    MAX_RESULTS: 10,
} as const;

Conditional types

type IsString<T> = T extends string ? true : false;

Indexed access types

type PersonName = Person["name"];

Mapped types

type Optional<T> = {
    [K in keyof T]?: T[K];
};

Type guards with never

function assertNever(value: never): never {
    throw new Error(`Unexpected value: ${value}`);
}

Module Imports/Exports

// Export
export function add(a: number, b: number): number {
    return a + b;
}

// Import
import { add } from "./math";

Intersectio types

type Admin = {
    name: string;
    privileges: string[];
};

type Employee = {
    name: string;
    startDate: Date;
};

type ElevatedEmployee = Admin & Employee;

Type guards for discriminated unions

type Result<T> = { success: true; value: T } | { success: false; error: string };

function handleResult(result: Result<number>) {
    if (result.success) {
        console.log(`Result is ${result.value}`);
    } else {
        console.error(`Error: ${result.error}`);
    }
}

Conditional (ternary) operator

type User = {
    isAdmin: boolean;
};

type Permission = User["isAdmin"] extends true ? "Admin" : "User";

Keyof and Lookup Types

type User = {
    id: number;
    name: string;
    email: string;
};

type UserKeys = keyof User;
type UserType = User["name"];

Type inference with Generics

function firstElement<T>(arr: T[]): T {
    return arr[0];
}

const element = firstElement([1, 2, 3]); // element is inferred as number

Conditional types with generics

type TypeName<T> = T extends string ? "string" : T extends number ? "number" : "other";

Template literal types

type Greeting = `Hello, ${string}!`;
const greeting: Greeting = "Hello, TypeScript!";

Using mapped types with partial

type PartialUser = Partial<User>;

Using mapped types with record

type CountryPopulation = Record<"USA" | "Canada" | "Mexico", number>;

Type-safe Event Handling

class EventEmitter<T> {
    private listeners: Record<string, ((data: T) => void)[]> = {};

    on(event: string, listener: (data: T) => void) {
        if (!this.listeners[event]) {
            this.listeners[event] = [];
        }
        this.listeners[event].push(listener);
    }

    emit(event: string, data: T) {
        const eventListeners = this.listeners[event];
        if (eventListeners) {
            eventListeners.forEach((listener) => listener(data));
        }
    }
}

Indexed access with tuples

type Tuple = [string, number, boolean];
type SecondElement = Tuple[1]; // number

Recursive types

type TreeNode<T> = {
    value: T;
    left?: TreeNode<T>;
    right?: TreeNode<T>;
};

Type-safe object merging

type Merge<T, U> = {
    [K in keyof T]: K extends keyof U ? U[K] : T[K];
};

const mergedObj = merge({ a: 1, b: "string" }, { b: 2, c: true });

using the keyof operator for object keys

function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

const user = { id: 1, name: "John" };
const id = getProperty(user, "id");

Function overloading

function createElement(tag: "div"): HTMLDivElement;
function createElement(tag: "span"): HTMLSpanElement;
function createElement(tag: string): HTMLElement {
    return document.createElement(tag);
}

Discriminated Union with Function Types

type Shape =
    | { kind: "circle"; radius: number }
    | { kind: "rectangle"; width: number; height: number };

function calculateArea(shape: Shape): number {
    switch (shape.kind) {
        case "circle":
            return Math.PI * shape.radius ** 2;
        case "rectangle":
            return shape.width * shape.height;
    }
}

Conditional type inference with infer

type ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

Using TypeScript with React

interface Props {
    name: string;
}

const MyComponent: React.FC<Props> = ({ name }) => {
    return <div>Hello, {name}!</div>;
};

Type-safe Axios Requests (Example)

import axios from "axios";

interface ApiResponse<T> {
    data: T;
    status: number;
}

async function fetchData<T>(url: string): Promise<T> {
    const response = await axios.get<ApiResponse<T>>(url);
    return response.data.data;
}