The Battle of Extends and Intersection in Typescript

Typescript's concept of extension is akin to C++'s inheritance.
Intersection in Typescript involves creating a new object with
all the properties from the intersected classes.

Why utilize intersection when extends keyword can already
merge all members from both classes into the derived class?

When would using intersection be more advantageous over
extension in certain scenarios?

https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types

Answer №1

While they may seem similar, there are distinct differences between them:

  1. extends is only applicable to types with statically known members:
type SimpleType = {x: string};
interface SimpleInterface extends SimpleType {} // valid
type ComplexType = {x: string} | {x: number};
// error: An interface can only extend an object type or intersection of object types with statically known members.
interface ComplexInterface extends ComplexType {}

Type intersection is a more general type operation that can be applied to any two types and provide a result; extends is specifically for interfaces and interface-like types (as well as classes).

  1. When extending from a parent interface, creating fields with the same name but wider types is not allowed:
interface Parent {
    x: string | number;
}
interface Child1 extends Parent {
    x: string; // valid
}
interface Child2 extends Parent {
    x: string | number | boolean; // error
}

However, type intersection does not have this restriction:

type IntersectedChild = Parent & {x: string | boolean}; // valid
// IntersectedChild will have property 'x' as an intersection
// of 'string | number' and 'string | boolean', resulting in a 'string':
type IntersectedChildX = IntersectedChild['x']; // string
  1. When using extends with classes, the child class inherits all implementations from its parent; whereas type intersection operates solely at the type level, so if you define classes A and B with type C = A & B, C remains a type rather than a class, requiring manual construction of an object that meets the constraints of C (containing all members of A and B with matching visibility levels).

For further clarification, refer to this playground link with the examples showcased above.

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

Acquiring the index of a selector event within a list of dynamic elements

I am seeking guidance on how to go about solving the issue of obtaining an event index. I have a hunch that closures might play a role in the solution and would appreciate some insights. Initially, I dynamically build an HTML5 video container using an aja ...

Exceeded Limit: Google Maps API cannot process more than 10 destinations at this time

After spending the entire day researching, I am still unable to find a solution that solves my issue. I am utilizing the Google Maps Distance Matrix Service with 1 origin and 14 destinations. While testing the modified sample code from Google (https://deve ...

Issue with Sliding Transition in React Material UI Drawer Component

I developed a custom drawer component for my React application const CustomSidebar = () => { return ( <Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)} > <Box> <Navigator / ...

Consistently receiving the identical result even when the checkbox remains unselected

Displaying a Checkbox Input <input id="idCheckbox" name="check" type="checkbox" value="AllValue" style="width: auto; height: auto; font-weight: bolder;" data-bind="checked: idCheckbox" /> The checkbox input will always have the value "AllValue ...

Using Vue.js as a view engine for ExpressJS

I'm on the hunt for a solution similar to React for ExpressJS, but tailored for Vue.js instead. Currently, I'm facing challenges when it comes to passing data from my database (mongoose) to my view. Right now, I'm utilizing the handlebars v ...

Typescript - Troubleshooting undefined error with static variables

My node API app is developed using express and typescript. The static variable of the Configuration Class is initialized with required configuration before starting the server. However, when I try to use this static variable in a separate TypeScript class ...

TS2339: The 'contacts' property is not found within the 'Navigator' type

I am currently developing a contacts application that utilizes the Apache Cordova plugins for contacts. However, when attempting to run the npm run bundle command for my application, I encountered the error mentioned in the title above. Can anyone guide me ...

Is it possible to capture a Browser TAB click event using JavaScript or AngularJS?

How can I trigger an event when returning to a tab? For instance: Let's say I have opened four tabs in the same browser with the same URL: such as: http://127.0.0.1:/blabla http://127.0.0.1:/blabla http://127.0.0.1:/blabla http://127.0.0.1:/blabla ...

Is it possible to update the content page without having to refresh the master page?

Our website features a Master page with main menu options and corresponding sub menus. When a user clicks on a main menu item, the relevant sub menus should be displayed. After clicking on a sub menu, the content page should update without having to refr ...

Grab and drop into place

I have been searching for solutions, but so far I haven't found anything that works for my specific case. I have an upload button that currently works on a click event, but I also want it to be able to drag and drop files for uploading. Here is the H ...

Exploring the depths of JSON using @attributes and @association in the realm of JavaScript and AngularJS

Currently, I am working on a project that involves utilizing an API for data retrieval, updates, and deletions. The API in question is the prestashop API. While I have managed to retrieve data and update certain items successfully, I encountered an issue. ...

The server gets blocked by numerous AJAX GET requests happening at the same time until the data gets returned

In my Rails application, I am using the gridList library to display charts. The chart data is fetched asynchronously from a controller method in JSON format via AJAX. Upon initial page load, each gridlist item displays a loading icon while simultaneously m ...

The JavaScript function prints the variable using `console.log(var)`, however, it does not assign `var2` to

I've been following a tutorial on implementing push notifications in VueJS from this link. After running the register function on the created hook, I encountered an issue: register() { if ("serviceWorker" in navigator && "PushManager" in window ...

Click the link to capture the ID and store it in a variable

Currently working on a project involving HTML and JavaScript. Two HTML pages ("people.html" and "profile.html") are being used along with one JavaScript file ("people.js") that contains an object with a list of names, each assigned a unique ID: var person ...

Attempting to incorporate country flags into the Currency Converter feature

www.womenpalace.com hello :) i'm looking to customize my Currency Converter with Flags images. this is the code for the converter: <select id ="currencies" class="currencies" name="currencies" data-default-shop-currency="{{ shop.currency }}" ...

What is the best way to switch a single class using jQuery without impacting other elements with the same class

I'm in the process of implementing a commenting system similar to Reddit on my website. Each comment is equipped with a small button in the top right corner that allows users to collapse the comment. To achieve the collapsing effect, I am utilizing j ...

Tips for incorporating auth0 into a vue application with typescript

Being a beginner in TypeScript, I've successfully integrated Auth0 with JavaScript thanks to their provided sample code. However, I'm struggling to find any sample applications for using Vue with TypeScript. Any recommendations or resources would ...

Place the div absolutely on top of the Flash content

Can a <div /> be absolutely positioned over a Flash banner without including wmode="transparent" in the banner? I am trying to display a lightbox above my ads, but I cannot make changes to the banners since they are provided by a third party. Edit: ...

Passing User Authentication State from Express/Passport to a React Client: A Step-by-Step Guide

I want to pass a basic boolean value const isLoggedIn = true; (provided by Passport) from my Express backend to my React frontend. I'm looking for an alternative to embedding it in the HTML through a templating engine. This seems like a common req ...

Beginning the default execution right away

Currently employing jQuery. This is my code snippet: $("#input").keypress(function(event) { getConversion(); }); Is there a way to ensure that the key pressed is first added to #input before triggering the getConversion() function? ...