Describing union of input types in TypeScript

Viewed 154

Let's say we have a wrapper object:

interface Wrapper<T> {
  value: T
}

I want to design a function that receives Wrapper objects as arguments (with possibly different T) and returns one of them:

function <T extends ReadonlyArray<Wrapper<any>>>(...args: T) { ... }

The return type of such function should be Wrapper<(union of input Ts)>. How do I describe such return type in Typescript, without losing the input types (that is, not Wrapper<any>)?

1 Answers

You are on the right track. The function will capture the correct types, the any in the constraint is used as a wild card, the any will not make it into T (depending on variance you could replace it with unknown or never but it's usually not worth it)

If T contains an array of wrappers, you can get a union of the types passed to wrppper using an type index query:

function getOne<T extends ReadonlyArray<Wrapper<any>>>(...args: T): Wrapper<T[number]['value']> {
    return args[0];
}

let x = getOne({
    value: { a: 1}
}, {
    value: { b: 1}
})

// let x: Wrapper<{
//     a: number;
// } | {
//     b: number;
// }>

Playground Link

Related