Interface vs Type in TypeScript: Unraveling the Differences

When navigating the TypeScript landscape, understanding the nuances between interfaces and type aliases is crucial. Both offer powerful ways to define shapes, but they exhibit distinct behaviors.

Declaration and Extension:

  • Interface: It employs the interface keyword, focusing on the declaration. Interfaces can extend other interfaces or classes, making them highly extensible.

    Example:

      interface Animal {
        name: string;
      }
    
      interface Bear extends Animal {
        honey: boolean;
      }
    
  • Type Alias: It uses the type or type alias keyword, and while it can use union, intersection, and mapped types for composition, it cannot be reopened to add new properties.

    Example:

      type Animal = {
        name: string;
      };
    
      type Bear = Animal & {
        honey: boolean;
      };
    

Declaration Merging:

  • Interface: Interfaces can be merged if declared multiple times with the same name. This allows for a convenient way to extend or update existing interfaces.

    Example:

      interface Window {
        title: string;
      }
    
      interface Window {
        ts: TypeScriptAPI;
      }
    
  • Type Alias: Type aliases cannot be merged. Attempting to redefine a type alias with the same name results in a compilation error.

    Example:

      type Window = {
        title: string;
      };
    
      type Window = {
        ts: TypeScriptAPI;
      }
      // Error: Duplicate identifier 'Window'.
    

Primitives and Constraints:

  • Interface: Interfaces can’t extend primitive types, and they are often used to define constraints on generics.

    Example:

      interface Admin extends User {
        role: "guest" | "admin";
      }
    
  • Type Alias: Type aliases can extend primitive types, and they, too, can define constraints on generics.

    Example:

      type Admin = User & {
        role: "guest" | "admin";
      };
    

Intersection & Union:

  • Interface: Interfaces can be used with extends to create intersection types.

  • Type Alias: Type aliases can be used with & for intersection types and | for union types.

Mapped Types:

  • Interface: Interfaces cannot be used with mapped types.

  • Type Alias: Type aliases can use mapped types for transformations on property names and types.

Implements Keyword:

  • Interface: Classes use the implements keyword to implement interfaces.

  • Type Alias: No implements keyword is used when using type aliases with classes.

Object Literal Types:

  • Interface: Interfaces are often used for defining object shapes.

  • Type Alias: Type aliases can also be used for defining object shapes.

In summary, while both interfaces and type aliases have similarities, such as defining shapes and extending types, their subtle differences make each suitable for specific scenarios. The choice between them depends on the nature of your project and the characteristics you require.

Stay tuned for more deep dives into TypeScript’s rich features and best practices!