Combining interfaces in Typescript

UPDATE
i stumbled upon this solution

type Merge<T, U> = {
  [K in keyof T | keyof U]: K extends keyof U? U[K]: K extends keyof T? T[K]: never;
};

is there an equivalent in typescript using the spread operator?

type Merge<T, U> = ...[K in keyof T]: T[K], ...[K in keyof U]: U[K]

my objective is to combine two types into a new type. The keys of the second type will override keys of the first type. for example:

interface User {
  id: string;
  name: string;
  age: number;
  role: "admin" | "moderator" | "user";
  occupation: string;
}
interface User2 {
  id: string;
  name: string;
  age: boolean;
}

type mergedType = Merge<User, User2>

after merging, the interface type will look like this->

{
  id: string;
  name: string;
  age: boolean;
  role: "admin" | "moderator" | "user";
  occupation: string;
}

Answer №1

In a scenario where the types never clashed, it would simply be User & User2. However, in your specific case, User has age: number while User2 has age: boolean, resulting in a conflict.

To address this, you can implement the approach you mentioned (using the definition of the second type) by utilizing a mapped type combined with a conditional type to select the property type from B if present or from A if not, merging it with the second type being merged:

type MergeTypes<A, B> = {
    [key in keyof A]: key extends keyof B ? B[key] : A[key];
} & B;

(Alternatively, there is the more straightforward option of

type MergeTypes<A, B> = Omit<A, keyof B> & B;
, as highlighted by M. Erim Tuzcuoglu and this answer on another post.)

Example of usage:

type MergedType = MergeTypes<User, User2>;

Playground link

This is how the process works:

  • key in keyof A ensures that the mapped type will have a key for each key in type A
  • key extends keyof B checks if the key is also present in type B
    • If so, we use B[key] as the property type; otherwise, we utilize A[key]
  • The output consists only of properties from A (with the respective type from
    B</code if applicable), excluding those unique to <code>B
    . To include these additional properties, we append & B at the end.

Answer №2

Perhaps you're seeking guidance from this

Check out this functional demo:

interface Customer {
  id: string;
  name: string;
  age: number;
  role: "admin" | "moderator" | "user";
  occupation: string;
}
interface Customer2 {
  id: string;
  name: string;
  age: boolean;
}

type Customize<T, R> = Omit<T, keyof R> & R;

var y: Customize<Customer, Customer2> = {id: '123', name: 'name', age: true, occupation: 'occ', role: 'admin'};
console.log(y);

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

Establishing a Recyclable Testing Rendering Method in redux toolkit version 2

In the era of Redux Toolkit v2, a noticeable change occurred with the absence of the EmptyObject type and the unavailability of the PreloadedState type in the @reduxjs/toolkit package. This has led to a requirement of defining all reducers inside the pre ...

Using Vue and TypeScript to define components

Whenever I attempt to install vue-class-component, vue-class-component, or vue-property-decorator, I encounter the following error message: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a ...

The error message states that the property 'id' is not found on the 'User' type when using Passport and Typescript

When I try to access req.user.id while using PassportJS in Express with Typescript, I encounter the following error: Property 'id' does not exist on type 'User'.ts(2339) Upon logging req.user to the console, the id property is clearly ...

Please ensure that the table contains all the records corresponding to the respective days

I am struggling with figuring out how to display a record of classes in my table view. The UX prototype I need to follow is shown https://i.stack.imgur.com/CISYn.png (the days of the week are in Portuguese: horario = time, segunda = Monday, terça = Tuesda ...

The componentWillReceiveProps method is not triggered when a property is removed from an object prop

Just starting out with React, so I could really use some assistance from the community! I am working with a prop called 'sampleProp' which is defined as follows: sampleProp = {key:0, value:[]} When I click a button, I am trying to remo ...

Encountering a runtime issue with socket.io when using typescript that has been bundled by

Recently, I attempted to implement web sockets using socket.io in a Node server written in TypeScript with ExpressJS and bundled with Webpack. The server code is structured as follows: import * as Express from "express"; import * as SocketIO from "socket ...

Create a new project using Firebase Functions along with a Node.js backend and a React.js frontend

In the process of developing my application, I have chosen to utilize node.js, express.js, and Firebase with firebase functions, all coded in TypeScript. For the client side framework, I am interested in incorporating react.js. Currently, I have set up nod ...

"Encountered an issue with Next-Auth session returning as undefined in getServerSideProps using NextJS version 13.2

When inspecting the code below, session is found to be undefined upon logging from the client side after being transferred from getServerSideProps. import { getServerSession } from 'next-auth/next'; import { authOptions } from './api/auth/[. ...

Having trouble implementing the ternary operator (?) in TypeScript within a Next.js project

Trying to implement a ternary operator condition within my onClick event in a Next.js application. However, encountering an error indicating that the condition is not returning any value. Seeking assistance with resolving this issue... https://i.stack.img ...

Developing UIs in React that change dynamically according to the radio button chosen

Problem Statement I am currently developing a web application feature that computes the heat insulation factor for a specific area. You can view the live demonstration on Codesandbox <a href="https://codesandbox.io/p/github/cloudmako09/btu-calc/main?im ...

Create an HTML button on the homepage that directs users to the "about" page

I've been struggling to make a button in my Ionic app navigate to a different page upon clicking. Despite being new to Ionic, I've spent hours trying to solve this issue. Below is the HTML code in home.page.html: <ion-header> &l ...

Creating a WebExtension using Angular and TypeScript

I am currently working on creating a WebExtension using Angular and Ionic. The extension successfully loads the application and enables communication between Content Script and Background Script. However, I am facing an issue where the TypeScript code is n ...

Transforming Uint8Array into BigInt using Javascript

I've come across 3 different ways to convert a Uint8Array to BigInt, but each method seems to produce varying results. Can someone clarify which approach is correct and recommended? Utilizing the bigint-conversion library. The function bigintConversi ...

transform json array into a consolidated array by merging identical IDs

I need to transform an array into a different format based on the values of the ID and class properties. Here is the initial array: const json = [{ "ID": 10, "Sum": 860, "class": "K", }, { "ID": 10, "Sum": 760, "class": "one", }, { "ID": ...

What sets apart the concepts of Boolean and boolean when it comes to Typescript?

I would like to understand the distinction between Boolean and boolean in Typescript. Can anyone provide an explanation? ...

Child component experiencing issues with Materialize Pagination and Sorting functionalities not functioning

New to materialize pagination and currently working on the hierarchy below: app modules > list > list.component app.component Implemented a sample code example in app.component which worked perfectly. However, encountered issues when trying to imp ...

What is the most suitable data type to represent an empty object?

When I declared the return type of the function below as {}, eslint flagged an error stating not to use {} as a type because it actually means "any non-nullish value". After understanding the meaning behind this error, I realize that specifying return typ ...

The element within the iterator is lacking a "key" prop, as indicated by the linter error message in a React component

Encountering an error stating Missing "key" prop for element in iteratoreslintreact/jsx-key {[...Array(10)].map((_) => ( <Skeleton variant="rectangular" sx={{ my: 4, mx: 1 }} /> ))} An attempt to resolve this issue was made ...

Guidelines on encoding query parameters for a tRPC query with the fetch function

As stated in the tRPCs official documentation, the query parameters must adhere to this specific format: myQuery?input=${encodeURIComponent(JSON.stringify(input))} Here is an example of a procedure: hello: publicProcedure .input(z.object({ text: z.s ...

Is it possible to activate every function within a prototype?

When presented with a class structure as demonstrated below, I am able to iterate through all its PropertyNames using console.log. class Security { constructor(param: ParamType) { this.method1(param); ... this.methodN(param); } method1(p ...