Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Merge two types/interfaces and keep all generics valid

I want to merge two types and also keep the generics valid. for example

Type 1

interface Request<P extends core.Params = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = core.Query> extends core.Request<P, ResBody, ReqBody, ReqQuery> { }

Type 2

type Auth = {
  user: User
}

I want my new type to be a merge of these two, where the type can receive all those generics.

Right now I am just merging them, but then I am not able to use generics of the Request type.

Currently I am just merging these two.

export type Merge<FirstType, SecondType> = Omit<FirstType, keyof SecondType> & SecondType;

Of course I can do all this manually, but this case is repeating in my project, I want a utility method which can do this for me. For example

MergeWithGenerics<Request, Body>

Where the new type keeps all generics of the first arg.

I don't know if its possible or not, but it would be really great if someone can help me with this.

like image 846
Sarmad Shah Avatar asked Apr 24 '20 12:04

Sarmad Shah


People also ask

What is a generic interface in typescript?

Summary: in this tutorial, you will learn how to develop TypeScript generic interfaces. Like classes, interfaces also can be generic. A generic interface has generic type parameter list in an angle brackets <> following the name of the interface:

How to merge two interfaces with typescript?

To merge two interfaces with TypeScript, we can use extends to extend multiple interfaces. to create the IFooBar that extends IFoo and IBar. This means IFooBar has all the members from both interfaces inside. To merge two interfaces with TypeScript, we can use extends to extend multiple interfaces.

What is declaration merging in typescript?

Declaration merging is when the TypeScript complier merges two or more types into one declaration provided they have the same name. TypeScript allows merging between multiple types such as interface with interface, enum with enum, namespace with namespace, etc. One notable merge that isn’t permitted is class with class merging.

How to use type parameters in a generic interface?

A generic interface has generic type parameter list in an angle brackets <> following the name of the interface: interface interfaceName<T> { // ... } This make the type parameter T visible to all members of the interface. The type parameter list can have one or multiple types. For example: interface interfaceName<U,V> { // ... }


Video Answer


1 Answers

You can't pass a generic type (without parameters) to another generic type.

interface Generic<P> { }
type Id<T> = T
type G = Id<Generic>; // Generic type 'Generic<P>' requires 1 type argument(s).(2314)

That being said, your definition of Merge seems to be a pretty good shorthand for what you're trying to do. Merge<Request<Params, ResBody, ReqBody, Query> & Auth> doesn't seems a lot bigger then RequestWithAuth<Params, ResBody, ReqBody, Query>.

A variation of the proposal from @leonardfactory, might also simplify a bit:

 type ExtendedRequest<Extension, P, TRes, TReq, TQuery> = Merge<Request<P, TRes, TReq, TQuery>, Extension>
like image 80
Tiberiu Maran Avatar answered Oct 25 '22 08:10

Tiberiu Maran