Is there a way to consolidate two interface types while combining the overlapping properties into a union type?

Is there a way to create a type alias, Combine<A, B>, that can merge properties of any two interfaces, A and B, by combining their property types using union?

Let's consider the following two interfaces as an example:

interface Interface1 {
  type: string;
  another: bool;
}
interface Interface2 {
  type: number;
}

If we were to use

Combine<Interface1, Interface2>
, the resulting type should look like this:

type Result = {
  type: string | number;
  another: bool;
}

Answer №1

Begin by extracting all keys present in set A but not in set B, along with keys from set B that are not found in set A. For overlapping keys, define the union explicitly:

type Combine<A, B> = 
    Omit<A, keyof B> // elements in A not in B
  & Omit<B, keyof A> // elements in B not in A
  & { [K in keyof A & keyof B]: A[K] | B[K] }; // combination of both.

It is worth noting that specifying that certain keys may be absent in one set or the other can be achieved using Partial with the Omit:

type Combine<A, B> = 
    Partial<Omit<A, keyof B>> // potentially elements in A not in B
  & Partial<Omit<B, keyof A>> // possibly elements in B not in A
  & { [K in keyof A & keyof B]: A[K] | B[K] }; // combination of both.

Update: Upon Aaronium's inquiry about utilizing unions, an improved approach has been devised, where T extends any ? X : never is leveraged to expand all keys existing in any element within a union and then consolidate a union of corresponding values across interfaces. This results in a streamlined method:

// retrieves all viable keys from all interfaces within a union.
type AllKeysOf<T> = T extends any ? keyof T : never
// essentially performs T[K], but for unionized T it only yields T[K] for valid key members within the union.
type Get<T, K extends keyof any, Fallback=never> = T extends Record<K, any> ? T[K] : Fallback
// combines a union of interfaces, merging common keys into a union of possibilities.
type Combine<T> = {[K in AllKeysOf<T>]: Get<T,K>}

type TEST = Combine<{a:1} | {a:2, b:10} | {b: 11}>
// TEST = {a: 1|2, b: 10|11}

Keep in mind that adjusting the generic Fallback in Get</code to <code>never will exclude union elements lacking that key. Alternatively, setting it to undefined suggests that keys defined in some interfaces but not all might result in undefined values, resembling optionality. The exact interpretation of these different handling methods largely relies on your specific scenario, so experimentation with both never and undefined is recommended to determine desired behavior.

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

Error message in Angular 2 RC-4: "Type 'FormGroup' is not compatible with type 'typeof FormGroup'"

I'm currently facing an issue with Angular 2 forms. I have successfully implemented a few forms in my project, but when trying to add this one, I encounter an error from my Angular CLI: Type 'FormGroup' is not assignable to type 'typeo ...

Disappearing act: Ionic tabs mysteriously disappear when the back button

Whenever I navigate in my ionic app, I notice that the tabs-bar disappears when I go to different pages and then return to the tabs. See Demo Code tab1 Here is a sample link to navigate to other pages: <ion-label routerDirection="forward" [routerLi ...

The information retrieved from the API is not appearing as expected within the Angular 9 ABP framework

I am facing an issue with populating data in my select control, which is located in the header child component. The data comes from an API, but for some reason, it is not displaying correctly. https://i.stack.imgur.com/6JMzn.png. ngOnInit() { thi ...

Attempting to convert numerical data into a time format extracted from a database

Struggling with formatting time formats received from a database? Looking to convert two types of data from the database into a visually appealing format on your page? For example, database value 400 should be displayed as 04:00 and 1830 as 18:30. Here&apo ...

Is it possible to make the 'keyof' property optional?

Illustrate an interface in the following way interface Properties { apple?: string banana?: string cherry?: string date: string } Executing this code works as expected type Sample1 = { [P in keyof Properties]: Properties[P] } const s1: Sample1 ...

Utilizing symbols as a keyof type: A simple guide

Let's consider the following: type Bar = keyof Collection<string> In this scenario, Bar denotes the type of keys present in the Collection object, such as insert or remove: const x: Bar = 'insert'; ✅ But wait, the Collection also c ...

Issues with naming in Gulp, Angular2 Final, and Visual Studio: "Cannot find name" and "Duplicate identifier" errors

Recently, I updated my project to utilize the final release of Angular 2 and also upgraded Visual Studio to use TypeScript 2.0.3 from the Tool -> Extensions and Updates manager. I compile my TypeScript using Gulp, and it compiles without any errors. Howev ...

Fetching data from an API using Observables in Angular

I am facing a challenge with an API endpoint that returns an array of strings in JSON format. My goal is to display these contents on a webpage using an Angular Service. Below is the code snippet I have implemented so far (working with Angular 7): export ...

Guide on automatically inserting a colon (:) after every pair of characters in Angular

I am looking to automatically insert a colon (:) after every 2 characters in my input field: HTML <input nz-input type="text" appLimitInput="textAndNumbers" name="mac" formControlName="mac" (keydown.space)=&qu ...

VS Code is flagging TypeScript errors following the recent software update

After updating my VS Code, I started seeing TypeScript error messages like the following: ButtonUnstyled.types.d.ts: Module '"/components/node_modules/@types/react/index"' can only be default-imported using the 'esModuleInterop&a ...

Experience the dynamic live preview feature of Sanity integrated with NextJS 13

I am facing an issue with checking if preview mode is activated on my website. While following a YouTube tutorial, I realized that the instructions may be outdated with the latest NextJS update. This was the code snippet I was originally working with to ...

What could be causing the errors I'm encountering in my TypeScript component within AngularJS?

I am working with an AngularJS component written in TypeScript called news.component.ts. This component makes a call to a service named google.service.ts in order to fetch news RSS using a service that converts XML to JSON. Within the NewsComponent, I hav ...

Testing TypeScript functionality within the Eclipse environment with unit tests

Is there a method to test TypeScript code on the Eclipse platform? I'm searching for something similar to JUnit, but most of the tools I've come across are geared towards Visual Studio. ...

Error encountered in Intellij for Typescript interface: SyntaxError - Unexpected identifier

I am currently testing a basic interface with the following code: interface TestInterface { id: number; text: string; } const testInterfaceImplementation: TestInterface = { id: 1, text: 'sample text' }; console.log(testInterface ...

Using event.target to pass HTML form data to FormData is causing an error stating that the Argument of type 'EventTarget' cannot be assigned to a parameter of type 'HTMLFormElement'

Looking to extract data from a form and store it in FormData: const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); const value = formData.get(' ...

Issue: Undefined default value property in TypescriptDescription: In Typescript,

export class EntityVM implements EntityModel { ... Properties... ... constructor(newEntity: EntityModel, isCollapsed = false) { ... Properties... ... this.isCollapsed = isCollapsed; } } public myFunction(myEntity: EntityVM) { / ...

Ensuring User Authentication in Angular with Firebase: How to Dynamically Hide the Login Link in Navigation Based on User's Login Status

After successfully implementing Angular Firebase email and password registration and login, the next step is to check the user's state in the navigation template. If the user is logged in, I want to hide the login button and register button. I tried s ...

Is there a way to verify if the database has been successfully saved and the API call has been

I am currently in the process of developing a function that calls two other functions. Function 1 is responsible for saving an object to a database, while function 2 performs an API call. async createMSCalendarEntry(start: Date, end: Date, name: string ...

What steps should I take to fix this Angular 8 error?

Encountered an issue in ../node_modules/@angular/http/src/backends/jsonp_backend.d.ts:1:28 - error TS2307: Module 'rxjs/Observable' not found. 1 import { Observable } from 'rxjs/Observable'; ~~~~~~~~~ ...

How can I change an icon and switch themes using onClick in react js?

I have successfully implemented an icon click feature to change the colorscheme of my website (in line 21 and changeTheme). However, I also want the icon to toggle between FaRegMoon and FaRegSun when clicked (switching from FaRegMoon to FaRegSun and vice v ...