Everything You Need To Know About TypeScript

Written by sadanandgadwal | Published 2024/04/19
Tech Story Tags: typescript | typescript-tutorial | ts | js | javascript-frameworks | typescript-syntax | error-handling-in-typescript | typescript-fundamentals

TLDRThis comprehensive guide takes you through TypeScript's basics to advanced concepts like generics, modules, and decorators, enabling you to build organized and scalable codebases for modern web development projects.via the TL;DR App

From Fundamentals to Intermediate Techniques for Effective Developmen


TypeScript is an open-source programming language developed by Microsoft that builds upon JavaScript by adding optional static typing, interfaces, classes, and other features to help developers write robust and scalable code. It compiles to plain JavaScript, making it compatible with existing JavaScript frameworks and libraries, while providing additional tooling and language features to improve developer productivity and code quality.

Beginner Level: Understand JavaScript Fundamentals: JavaScript fundamentals include knowledge of variables, data types, functions, objects, arrays, and control flow.

// Variables let x = 5; const y = "Hello";

// Data Types let num = 10; // Number let str = "Hello"; // String let bool = true; // Boolean let arr = [1, 2, 3]; // Array let obj = { name: "sadanandgadwal", age: 23 }; // Object

// Functions function greet(name) { return "Hello, " + name + "!"; } console.log(greet("sadanandgadwal")); // Output: Hello, sadanandgadwal!

// Objects let person = { name: "sadanandgadwal", age: 23, greet: function() { return "Hello, " + this.name + "!"; } }; console.log(person.greet()); // Output: Hello, sadanandgadwal!

Introduction to TypeScript:

TypeScript is a superset of JavaScript that adds optional static typing, interfaces, classes, and modules among other features.

// Define a function named greet that takes a parameter 'name' of type string and returns a string. function greet(name: string): string { return "Hello, " + name + "!"; }

// Call the greet function with the argument "sadanandgadwal" and log the returned value to the console. console.log(greet("sadanandgadwal")); // Output: Hello, sadanandgadwal!

// Define an interface named Person which specifies that any object implementing it must have a 'name' property of type string and an 'age' property of type number. interface Person { name: string; age: number; }

// Define a function named greetPerson that takes a parameter 'person' of type Person interface and returns a string. function greetPerson(person: Person): string { return "Hello, " + person.name + "!"; }

// Call the greetPerson function with an object that satisfies the Person interface, and log the returned value to the console. console.log(greetPerson({ name: "sadanandgadwal", age: 23 })); // Output: Hello, sadanandgadwal!

Setting Up Development Environment

Setting up the development environment involves installing Node.js and npm and configuring a TypeScript compiler like tsc.

Install Node.js and npm

Download and install from https://nodejs.org/

Install TypeScript globally

npm install -g typescript

Create a TypeScript file (example.ts)

Run the TypeScript compiler to generate JavaScript

tsc example.ts

Basic TypeScript Syntax

Basic TypeScript syntax includes declaring variables with types, understanding type inference, and using basic type annotations and assertions.

// Variable Declaration let x: number = 5; // Declare a variable 'x' of type number and assign it the value 5. const y: string = "Hello"; // Declare a constant 'y' of type string and assign it the value "Hello".

// Type Inference let num = 10; // TypeScript infers the type of 'num' as 'number' based on its initial value. let str = "Hello"; // TypeScript infers the type of 'str' as 'string' based on its initial value.

// Basic Type Annotations and Assertions let z: boolean; // Declare a variable 'z' of type boolean. z = true; // Assign the value true to the variable 'z'.

// Type Assertion let someValue: any = "this is a string"; // Declare a variable 'someValue' of type 'any' and assign it a string value. let strLength: number = (someValue as string).length; // Assert that 'someValue' is of type string and then access its length property. // Alternatively, you could use angle bracket syntax: let strLength: number = (<string>someValue).length;

console.log(x); // Output: 5 console.log(y); // Output: Hello console.log(num); // Output: 10 console.log(str); // Output: Hello console.log(z); // Output: true console.log(strLength); // Output: 16

Functions and Interfaces

In TypeScript, you can define function types and use interfaces to define object shapes and enforce contracts.

// Function Types // Define a type alias named GreetFunction representing a function that takes a 'name' parameter of type 'string' and returns a 'string'. type GreetFunction = (name: string) => string;

// Declare a variable 'greet' of type 'GreetFunction' and assign it a function expression that matches the defined function type. let greet: GreetFunction = function(name: string) { return "Hello, " + name + "!"; };

// Call the 'greet' function with the argument "sadanandgadwal" and log the returned value to the console. console.log(greet("sadanandgadwal")); // Output: Hello, sadanandgadwal!

// Interface // Define an interface named 'Person' with properties 'name' of type 'string' and 'age' of type 'number'. interface Person { name: string; age: number; }

// Define a function named 'greetPerson' that takes a parameter 'person' of type 'Person' interface and returns a 'string'. function greetPerson(person: Person): string { return "Hello, " + person.name + "!"; }

// Call the 'greetPerson' function with an object that satisfies the 'Person' interface, and log the returned value to the console. console.log(greetPerson({ name: "sadanandgadwal", age: 23 })); // Output: Hello, sadanandgadwal!

Working with Classes

Classes and inheritance in TypeScript allow you to create blueprints for objects with methods and properties. // Class class Person { // Define properties 'name' and 'age'. name: string; age: number;

// Define a constructor function that initializes 'name' and 'age' properties when a new object is created. constructor(name: string, age: number) { this.name = name; this.age = age; }

// Define a method named 'greet' that returns a greeting message using the 'name' property. greet(): string { return "Hello, " + this.name + "!"; } }

// Create a new instance of the 'Person' class with name "sadanandgadwal" and age 23. let person = new Person("sadanandgadwal", 23);

// Call the 'greet' method of the 'person' object and log the returned value to the console. console.log(person.greet()); // Output: Hello, sadanandgadwal!


Intermediate Level

Advanced Types

Advanced types in TypeScript include union types, intersection types, type aliases, conditional types, etc.

// Union Types // Declare a variable 'val' that can hold values of type 'number' or 'string'. let val: number | string; val = 10; // Assign a number to 'val' (valid). val = "Hello"; // Assign a string to 'val' (valid). // val = true; // Error: Type 'boolean' is not assignable to type 'number | string'

// Intersection Types // Define two interfaces 'A' and 'B' with different properties. interface A { propA: number; } interface B { propB: string; } // Create a new type 'C' which is an intersection of types 'A' and 'B'. type C = A & B; // Declare a variable 'obj' of type 'C' and assign an object with properties from both interfaces. let obj: C = { propA: 10, propB: "Hello" };

// Conditional Types // Define a conditional type 'TypeName<T>' which returns different strings based on the type of 'T'. type TypeName<T> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : "unknown"; // Declare variables of type 'TypeName' with different type arguments and assign them values. let a: TypeName<string> = "string"; // Output: "string" let b: TypeName<number> = "number"; // Output: "number" let c: TypeName<boolean> = "boolean"; // Output: "boolean" let d: TypeName<object> = "unknown"; // Output: "unknown"

console.log(val); // Output: Hello console.log(obj); // Output: { propA: 10, propB: "Hello" } console.log(a); // Output: string console.log(b); // Output: number console.log(c); // Output: boolean console.log(d); // Output: unknown 2

Generics

Generics allow you to write reusable, type-safe functions, interfaces, and classes.

// Generic Function // Define a generic function 'identity' that takes an argument 'arg' of type 'T' and returns the same type 'T'. function identity<T>(arg: T): T { return arg; } // Call the 'identity' function with a number and assign the result to 'num'. let num: number = identity(10); // Output: 10 // Call the 'identity' function with a string and assign the result to 'str'. let str: string = identity("Hello"); // Output: "Hello"

// Generic Interface // Define a generic interface 'Box<T>' with a single property 'value' of type 'T'. interface Box<T> { value: T; } // Create a variable 'box' of type 'Box<number>' and assign an object with a 'value' property of type number. let box: Box<number> = { value: 10 };

// Generic Class // Define a generic class 'Pair<T, U>' with two properties 'first' of type 'T' and 'second' of type 'U'. class Pair<T, U> { constructor(public first: T, public second: U) {} } // Create an instance 'pair' of the 'Pair<number, string>' class with values 10 and "Hello". let pair: Pair<number, string> = new Pair(10, "Hello");

console.log(num); // Output: 10 console.log(str); // Output: Hello console.log(box); // Output: { value: 10 } console.log(pair); // Output: Pair { first: 10, second: "Hello" }

Modules and Namespaces

Modules in TypeScript allow you to organize code into reusable units. Namespaces provide a way to logically group related code. // math.ts // Define a function 'sum' in the module 'math' that takes two numbers and returns their sum. export function sum(a: number, b: number): number { return a + b; }

// app.ts // Import the 'sum' function from the 'math' module. import { sum } from "./math"; // Call the 'sum' function and log the result to the console. console.log(sum(2, 3)); // Output: 5

// namespace // Define a namespace 'Math' containing a function 'sum' that calculates the sum of two numbers. namespace Math { export function sum(a: number, b: number): number { return a + b; } }

// app.ts /// <reference path="math.ts" /> // Use the 'sum' function from the 'Math' namespace and log the result to the console. console.log(Math.sum(2, 3)); // Output: 5

Decorators

Decorators are a feature of TypeScript that allow you to attach metadata to classes, methods, and properties. // Class Decorator // Define a class decorator 'Logged' that takes a target function. function Logged(target: Function) { // Log a message indicating that the class has been logged. console.log("Class logged:", target); }

// Apply the 'Logged' decorator to the 'MyClass' class. @Logged class MyClass {}

// Method Decorator // Define a method decorator 'Log' that takes target, key, and descriptor arguments. function Log(target: any, key: string, descriptor: PropertyDescriptor) { // Log a message indicating that the method has been logged. console.log("Method logged:", key); }

// Define a class 'MyService'. class MyService { // Apply the 'Log' decorator to the 'getData' method. @Log getData() {} }

// Property Decorator // Define a property decorator factory 'Configurable' that takes a boolean value. function Configurable(value: boolean) { return function(target: any, propertyKey: string) { // Define the property with configurable set to the provided value. Object.defineProperty(target, propertyKey, { configurable: value }); }; }

// Define a class 'MyComponent'. class MyComponent { // Apply the 'Configurable' decorator to the 'apiUrl' property with configurable set to false. @Configurable(false) apiUrl = "https://example.com"; }

// Console output console.log(MyClass); new MyService().getData(); console.log(Object.getOwnPropertyDescriptor(MyComponent.prototype, "apiUrl"));

Error Handling

Understanding how TypeScript handles errors and exceptions, including synchronous and asynchronous error handling strategies. // Synchronous Error Handling // Define a function 'divide' that takes two numbers and returns the result of dividing the first number by the second number. function divide(x: number, y: number): number { // Check if the second number is zero. if (y === 0) { // If it is zero, throw an error with a message. throw new Error("Division by zero"); } // If the second number is not zero, perform the division and return the result. return x / y; }

// Use a try-catch block to handle errors that may occur during the execution of the 'divide' function. try { // Call the 'divide' function with arguments 10 and 0. console.log(divide(10, 0)); // Output: Error: Division by zero } catch (error) { // If an error occurs, log the error message to the console. console.error(error.message); }

// Asynchronous Error Handling // Define an asynchronous function 'fetchData' that fetches data from a remote URL. async function fetchData() { try { // Attempt to fetch data from the specified URL. let response = await fetch("https://example.com/data"); // Check if the response is OK. if (!response.ok) { // If the response is not OK, throw an error with a message. throw new Error("Failed to fetch data"); } // If the response is OK, parse the JSON data. let data = await response.json(); // Log the parsed data to the console. console.log(data); } catch (error) { // If an error occurs during the fetch operation or parsing, log the error message to the console. console.error(error.message); } }

// Call the 'fetchData' function to initiate the asynchronous data fetching process. fetchData();

Conclusion

This guide covered TypeScript essentials, from syntax to advanced features like generics and decorators. Error handling strategies and integration with frameworks were explored. Mastering TypeScript empowers developers to create scalable, organized codebases, contributing effectively to modern web development projects.


Playground for Typescript Playcode.io is an online code editor and playground that allows users to write, edit, and execute HTML, CSS, and JavaScript code and even Typescript.


🌟 Stay Connected! 🌟 Hey there, awesome reader! 👋 Want to stay updated with my latest insights,Follow me on social media!

🐦 📸 📘 💻 🌐

Sadanand Gadwal


Written by sadanandgadwal | Software engineer 📚.Sharing coding related stuff. #sadanandgadwal
Published by HackerNoon on 2024/04/19