I fell into a case where I have the following variable :
var foo: Foo<string> | Foo<number> | Foo<boolean>;
generated dynamically (using keyof and stuff), which is fully intended at that point of the code. But then, I need to call methods inside that object defined like this :
class Foo<T> {
pipe(): Foo<T>;
pipe<A, B>(obj: Operator<T, A>, obj2: Operator<A, B>): Foo<B>;
pipe<A>(obj: Operator<T, A>): Foo<A>;
pipe(...obj: Operator[]): Foo<any> {
return new Foo();
}
}
The problem being, when I do the following :
const f = foo.pipe((bar) => new Foo());
bar
is infered as string
while I'd expect string | number | boolean
.
My guess here is that I need to convert Foo<string> | Foo<number> | Foo<boolean>
into Foo<string | number | boolean>
where it solves the problem.
How can I do such convertion ?
答案 0 :(得分:4)
您可以使用条件类型来实现此目的(联合类型分布在联盟上,在这种情况下可以帮助我们)
type UnionOfFooToFooOfUnion<T extends Foo<any> > = Foo< T extends Foo<infer U> ? U : never>
let foo!: Foo<string> | Foo<number> | Foo<boolean>;
let merged: UnionOfFooToFooOfUnion<typeof foo> = foo // we can just assign it
或者我们可以使用一个函数:
function mergeFoo<T extends Foo<any>>(foo: T): UnionOfFooToFooOfUnion<T> {
return foo;
}
mergeFoo(foo).pipe(s=> console.log(s)) // s is number | string | boolean