Determining the Best Use of Types Versus Interfaces in TypeScript

It's puzzling to me when you might opt for a type over an interface for a variable in typescript. Let's consider the two options provided:

type Player = {
    id: string;
    name: string;
    score: number;
}

interface Player {
    id: string;
    name: string;
    score: number;
}

You can declare a variable with both using const player: Player = .... However, there are certain abilities unique to the interface that the type lacks:

// Extension:
interface VIPPlayer extends Player {
    perks: string[];
    level: number;
}

// Using in abstract function:
abstract class Game {
    abstract startRound(player: Player): void;
}

class VIPGame extends Game {
    startRound(player: VIPPlayer) {
        ...
    }
}

These are just some of the distinctions.

So the question remains: In what scenarios would choosing a type be beneficial?

Answer №1

As of 12/15/2020, I have included additional information on the concept of "types" in TypeScript and similar ideas in other programming languages.

If I'm not mistaken, you may be uncertain about the distinction between an interface and a type.

In object-oriented programming, interfaces do not contain implementations, while types do. This implies that an interface is essentially useless unless a type implements it. Additionally, a type can only extend one other type but can implement multiple interfaces.

But what does this all mean...

Consider having a Car and a User - two vastly different types that may not seem immediately related practically. Some might suggest creating ICar and IUser for them. However, thinking in terms of interfaces this way can lead to confusion. Would it make sense for User to implement ICar or would ICar simply duplicate the functionality of Car? How would another programmer interpret the code?

Imagine wanting both objects to be "Self Describable" and provide information in the same manner. In such a scenario, you would create:

ISelfDescribable {
   getSelfDescription();
}

Subsequently, you could do the following:

Car implements ISelfDescribable {
   getSelfDescription(return "I am a car!");
}

User implements ISelfDescribable {
  getSelfDescription(...provide info differently...);
}

An array containing these objects would look like (imagine how you would achieve this without interfaces):

Array<ISelfDescribable>

Now, you (and any other developer inspecting the code) can be certain that each object in this array, regardless of its concrete type, follows the "behavior" defined by ISelfDesribable. When you think about it, there's actually no need to know the exact type as long as you're implementing the behavior. However, you still need the type to define that behavior.

Suppose someday you decide both objects should be "Insurable." They should both feature a method setInsurancePolicy. You could introduce IInsurable { setInsurancePolicy(policy: Policy) }, then implement it in the relevant types. Now you have objects that are both ISelfDescribable and IInsurable, and you can group those objects under either category in an array.

For me, the pivotal moment came when I grasped this idea: types (and type hierarchies) pertain to concrete entities, while interfaces deal with behaviors that can be shared across various types. There's more complexity to it, but at least you now have an understanding of why one would opt for an interface over a type. They represent distinct concepts in programming, despite their apparent similarities.

(Additional note: Languages like Scala approach interfaces differently. While they acknowledge "behaviors," the ability to implement and override these behaviors expands beyond conventional interface structures. This detail may delve too deeply into academic discussions for this context, but I digress – gotta vanquish all dungeon monsters, not just those tied to quests.)

12/15/2020: TypeScript: Types vs. Interfaces.

When should you choose one over the other? Once again, it hinges on what you intend to convey and how you plan to utilize it.

A "type" serves as the solution for "I require a contract, but it doesn't denote a behavior definition akin to an interface."

This ensures a clear semantic differentiation. An interface signifies a horizontal behavior, whereas a type defines...well, a type.

Furthermore, types offer functional advantages that interfaces lack, as they allow for combination and intersection. In React, it's often advised, "don't use interfaces since they aren't as versatile as types in terms of composition."

Imagine needing to specify a contract for two service calls' payloads. Interface wouldn't suit this purpose; it's reserved for horizontal behaviors. However, a "type" fits perfectly as it delineates the payload structure without prescribing a specific behavior.

And in cases where you must merge definitions from two payload types into one (e.g., for a UI component), language features like union/intersection become straightforward with "type" definitions.

The underlying principle remains intact; interfaces focus on behavioral aspects, while types handle vertical definitions that can be blended in diverse ways.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for changing CORS origins while the NodeJS server is active?

Currently, I am in the process of modifying the CORS origins while the NodeJS server is operational. My main goal is to replace the existing CORS configuration when a specific user action triggers an update. In my attempt to achieve this, I experimented w ...

Is there a way to stop a specific route in Express from continuing further execution without completing its function?

In my post route, I need to ensure that the user has provided all the necessary data in the body. To achieve this, I have added an if block to check for errors. router.post("/", (req, res) => { if(req.body.age < 24) { res.send("You are too you ...

The functionality of CSS transitions may be affected when dynamically adding a class

Creating a custom CSS for my main div: .main { height: 0%; position: absolute; width: 100%; z-index: 100; background: whitesmoke; bottom: 0; border-radius: 15px; padding: 20px; color: gray; left: 0; right: 0; transition: height 1s e ...

Uncovering design elements from Material UI components

The AppBar component applies certain styles to children of specific types, but only works on direct children. <AppBar title="first" iconElementRight={ <FlatButton label="first" /> }/> <AppBar title="second" iconElementRight={ <di ...

ajax causing issues with comments display on rails platform

Having trouble rendering comments using ajax in my rails app. The comments are only displayed after redirecting the page, even though they are successfully created. The issue seems to be with rendering comments using ajax and jquery! In my application.htm ...

Tips for retrieving information from an API and displaying it in a table

I'm struggling to retrieve data (an array of objects) from an API using a Token and display them in a table using Material-UI. However, I keep encountering the following error: Uncaught (in promise) SyntaxError: Unexpected token 'A', "Access ...

Learn how to showcase information stored in a JSON file within a list format and how to retrieve specific elements within a JavaScript object

I am struggling with populating a list in my Vue 3 app using a validated JSON file containing all the languages of the world. My lack of experience is making it difficult for me to access the inner parts of an object, so I need some guidance on that. JSON ...

Is there a way to store the outcome of an HTTP GET call in Angular 7 as a JSON file?

Hey there! I'm currently working on a web app that needs to make regular calls to a remote API. Since the response will always be consistent, I am planning to optimize the site's performance by storing the response data in a local JSON file. This ...

Having trouble with my loop using Jquery's $.get method

Having an issue with Jquery mobile / JavaScript I'm struggling to properly loop through the different values of data in my "get" function, where it should be sending ...cmd=PC&data=06464ff ...cmd=PC&data=16464ff ...cmd=PC&data=26464ff ...

Is my method of sending an email through angular correct?

I'm eager to expand my knowledge by learning something new. My goal is to utilize Angular and PHP to send an email. I am transforming my form data into an object and then attempting to pass this object as a variable to a PHP file. While I am successfu ...

Data from the table will be utilized in an SQL query according to a particular table row

My PHP script is set up to query my database and pull data based on the value of the acceptance field. SELECT * from database WHERE acceptance = 1 This process is working smoothly. Following that, my PHP script loops through the retrieved object to popul ...

During the scraping process with Puppeteer in NextJs, the execution context was terminated, possibly as a result of a navigation

I'm currently developing an application to search for my music on websites that host illegal content, with the intention of requesting its removal later. While working with puppeteer, I encountered an issue when trying to submit a search query and re ...

Unable to add an external NPM package for the creation of an Angular library

package.json was the first thing I worked on, { "name": "crypto-local-storage", "version": "0.0.1", "peerDependencies": { "@angular/common": "^12.2.0", "@angular/core ...

NodeAutoComplete: Enhanced Autocompletion for Node.js

I am attempting to utilize autocompletion of a JavaScript file with Node.js and Tern. However, the documentation for Ternjs is incredibly lacking. const tern = require("tern"); const ternServer = new tern.Server({}); const requestDetails = { "qu ...

Ensuring Safe Data Storage for an Angular 2 Project with Local Storage

One thing that worries me is the possibility of a hacker accessing the developer's console or local storage to alter user data, like the company name, and then gaining unauthorized access to my database. Here's a closer look at the issue: Curren ...

The leave animation for Angular's ngAnimate and ng-view feature appears to be malfunctioning

angular version: 1.6.1 I am attempting to create a fade in/out effect for my ng-view element, however, I am encountering an issue where only the enter animation is functioning properly. This is the relevant HTML code: <main class="main" ng-view>&l ...

Identifying on-the-fly adjustments in form input

I am facing an issue where I want to trigger an action when the inputs in my dynamically added form are changed, but unfortunately, it is not working as expected. The HTML code for embedding my form via iframe is shown below: <iframe onload="javascript ...

Tips for successfully including a positive sign character in string values within JSON in the URL's hash fragment

I am facing an issue with my JS (Angular) app where I load parameters from the URL fragment after the # sign. These parameters contain JSON objects, like this example: ...#filters={"Course":["ST_12.+13.12.2016 [Basel]"]} The aim is to open a data-grid an ...

Exploring front-end AJAX functionality within a WordPress plugin

As a newcomer to WordPress development, I have been working on writing an AJAX request within a WordPress plugin. To test this functionality, I initially sent the request to an external non-WP server where it worked without any issues. Following the guidel ...

The callback function in AngularJS filters

I'm currently using an AngularJS filter to sort through a list of items. Here is the Jade markup I am using: li(ng-repeat="parcel in parcels | filter : filterActiveAreaParcels") After the filter function runs and the elements are displayed in the DO ...