在下面的代码片段中,y
的类型被推断为 Bar<{}>
,由于双方差:
type Foo<A> = { type: "foo", x: A }
type Bar<A> = { type: "bar", y: A }
type FooBar<A> = Foo<A> | Bar<A>
type Opposite<A, FB extends FooBar<A>> = FB["type"] extends "foo" ? Bar<A> : Foo<A>
declare function process<A, FB extends FooBar<A>>(foo: FB): Opposite<A, FB>
const x: Foo<number> = null as any
const y = process(x) // Bar<{}>
我可以保留通用类型吗 A
这样process(x)
返回 Bar<number>
没有明确指定?
最佳答案
根据 FB
的类型约束推断 A
并不是 typescript 真正会做的事情。由于参数不提供推断 A
的站点,typescript 将为 A
推断最广泛的可能类型,即 {}
您可以使用条件类型从类型参数 FB
中提取 A
:
type Foo<A> = { type: "foo", x: A }
type Bar<A> = { type: "bar", y: A }
type FooBar<A> = Foo<A> | Bar<A>
type Opposite<A, FB extends FooBar<A>> = FB["type"] extends "foo" ? Bar<A> : Foo<A>
type FooBarParam<T> = T extends FooBar<infer A> ? A : never;
declare function process<FB extends FooBar<any>>(foo: FB): Opposite<FooBarParam<FB>, FB>
const x: Foo<number> = null as any
const y = process(x) // Bar<number>
关于typescript - 在不扩大的情况下推断通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53622852/