Typescript Features

Sraban Pahadasingh    June 25, 2024 01:13 AM

TypeScript concepts:

01. Type Assertion

Type assertion in TypeScript is a way to tell the compiler that you know more about the type of a value than TypeScript can infer automatically. It has two forms:

  • Angle-bracket syntax: <Type>value

    
      let myList = [1, 2, 3];
      let length1 = (<number[]>myList).length; // Using angle-bracket syntax
    
  • As syntax: value as Type

    
      let length2 = (myList as number[]).length; // Using 'as' syntax
    

Type assertion does not change the runtime behavior but helps TypeScript's type checker understand the intended type when the developer has more specific knowledge about it.

02. TypeScript Generics

Generics in TypeScript allow you to create reusable components that can work with a variety of data types while maintaining type safety. The syntax for generics involves using angle brackets (< >) to declare type parameters:


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

    let value = myMethod<number>(10); // Specify the type explicitly
    let anotherValue = myMethod("Hello"); // TypeScript infers the type

Generics can be used with interfaces, classes, functions, properties, and variables to create flexible and type-safe constructs.

03. typeof and keyof

  • typeof: Returns the type of a variable, function, or object.

      let x = 10;
      type T = typeof x; // T is 'number'
  • keyof: Returns the union of keys of a given type.

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

    type Keys = keyof Person; // Keys is 'name' | 'age'

04. Type Inference

Type inference in TypeScript refers to the ability of the type system to deduce types in certain situations based on the context and initialization values, without requiring explicit type annotations:


    let x = 10; // TypeScript infers 'number' type for x
    let y = "Hello"; // TypeScript infers 'string' type for y

Type inference reduces the need for manual type annotations, making code more concise while maintaining type safety.

05. Type Aliases

Type aliases in TypeScript allow you to create new names for existing types. They are particularly useful for defining complex types or for simplifying type annotations:


    type Container<T> = { value: T };

    let numContainer: Container<number> = { value: 10 };
    let strContainer: Container<string> = { value: "Hello" };

Type aliases improve code readability and maintainability by providing descriptive names for types.

06. Conditional Types

Conditional types in TypeScript enable the creation of types that depend on the relationships between types:


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

    let strType: TypeName<string> = "string";
    let numType: TypeName<number> = "number";

Conditional types use the extends keyword to check if a type satisfies a condition and then return different types based on that condition (X if true, Y if false).

07. Distributive Conditional Types

Distributive conditional types in TypeScript automatically distribute over union types:


    type BoxedValue<T> = { value: T };

    type BoxedNumber = BoxedValue<number | string>;
    // Equivalent to:
    // type BoxedNumber = BoxedValue<number> | BoxedValue<string>;

When a conditional type is applied to a union type, TypeScript applies the type condition to each constituent type of the union.

08. Object-Oriented Principles supported by TypeScript

TypeScript supports fundamental object-oriented principles such as:

  • Encapsulation: Bundling data and methods that operate on the data into a single unit (class).

  • Inheritance: Creating new classes (derived classes) from existing ones (base classes) to reuse and extend functionality.

  • Polymorphism: Using a single interface to represent multiple types (subtyping), allowing objects of different types to be treated as instances of a common superclass.

09. Awaited Type and Promise Improvements

TypeScript 4.3 introduced the Awaited type to extract the type awaited by a Promise:


    type Awaited<T> = T extends PromiseLike<infer U> ? U : T;

    async function fetchData(): Promise<string> {
      return "Data";
    }

    type Data = Awaited<ReturnType<typeof fetchData>>; // Data is 'string'

This improvement enhances type inference and provides better support for async functions and promise chains.

10. Recursive Type Aliases

Recursive type aliases in TypeScript allow defining types that reference themselves:


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

    let node: TreeNode<number> = {
      value: 10,
      left: {
        value: 5
      }
    };

Recursive type aliases are useful for defining recursive data structures like trees or linked lists.





Comments powered by Disqus