推断通用类型而不扩展

时间:2018-12-04 23:17:46

标签: typescript generics

在以下代码段中,由于双方差,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<{}>

Playground link

我可以保留通用类型A以便process(x)返回Bar<number>而不明确指定吗?

1 个答案:

答案 0 :(得分:3)

基于A的类型约束来推断FB并不是打字稿真正可以做的事情。由于参数没有提供推断A的站点,因此打字稿将推断A的最大可能类型,即{}

您可以使用条件类型从类型参数A中提取FB

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>