typescript - 在不扩大的情况下推断通用类型

标签 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>没有明确指定?

最佳答案

根据 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/

相关文章:

reactjs - 更好的语法来更新 redux 上的嵌套对象

javascript - 找不到模块拦截器 NestJS

C# Generic T Class TypeOf,这可能吗?

java - 具有泛型优势的多值类型映射

java - Java : extends ConcreteClass & I 中类的双重泛型约束

javascript - 在 Angular 6 中的组件之间共享逻辑时如何使用组合而不是继承?

javascript - FunctionComponent HOC 的正确类型

java - Java 泛型的 Number.valueOf() 实现

javascript - 转换 rjxs map 并展平/缩减为 flatMap

c# - Autofac 通用接口(interface)工厂