TrevTheDev
TrevTheDev

Reputation: 2737

How to merge type signatures with type properties

How does one merge types that have both call signatures and properties, without resorting to the intersection &? Intersection & creates types that are shown as e.g. Foo & { a: string } & { ()=>void } & Bar which may be hard to understand and abstract. When what one wants is {()=>void, a: string, b: string, c: number } which can be simpler to parse.

type Merge<T1, T2> = {
  [k in keyof T1 | keyof T2]: k extends keyof T1 ? T1[k] : k extends keyof T2 ? T2[k] : never;
}

type Foo = {
    (a: string): number;
    (a: number): number;
    foo1: string
}

type Bar = {
    bar1: number
}

type FooBar = Merge<Foo, Bar> // Merge excluding the call signatures - how does one include the call signatures?
/* end type should be:
type FooBar = {
    (a: string): number;
    (a: number): number;
    foo1: string
    bar1: number
}
and not be an intersection `Foo & Bar`
*/

code

Upvotes: 2

Views: 210

Answers (1)

jcalz
jcalz

Reputation: 327964

No, there is currently (TS4.7) no way to do this programmatically without using intersection types.

Mapped types do not preserve call signatures; there is a feature request at microsoft/TypeScript#29261 asking for some way to do this (well, it technically asks about construct signatures, but this comment mentions pulling signatures out of a type).

You could try to do this by making the intersection and then teasing out the resulting multiple call signatures (i.e., overloads), but unfortunately there is no good programmatic way to do this, see this answer for more information. Even if you could do this you'd probably have to resort to intersections to combine them again.

For now, I'd say that intersection types are the best you can do.

Upvotes: 1

Related Questions