【问题标题】:Infer generic type without widening在不扩展的情况下推断泛型类型
【发布时间】:2019-05-06 11:09:13
【问题描述】:

在下面的 sn-p 中,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&lt;number&gt; 而不明确指定它吗?

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    基于FB 的类型约束推断A 并不是打字稿真正会做的事情。由于参数不提供推断A 的站点,因此打字稿将推断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>
    

    【讨论】:

    • 我只是想告诉你我对你的打字稿答案印象深刻:-)
    • @zerkms 10x :) 很高兴得到赞赏 :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多