【问题标题】:Infer generic from type intersection从类型交集推断泛型
【发布时间】:2021-08-25 13:53:34
【问题描述】:

我试图用 typescript 推断类型交集的泛型,但不确定为什么编译器没有正确推断位置参数。例如:

type Brand<T, Y> = T & { __brand: Y}

type Foo = Brand<number, 'Hello'>

type ExtractT<T> = T extends Brand<infer A, unknown> ? A : never

function test(a: ExtractT<Foo>) {

}

test(1)  <-- error

我原以为ExtractT 可以从Brand&lt;number,&gt; 定义中提取number

有没有办法让这个从Brand 中提取number 类型?

游乐场链接:https://www.typescriptlang.org/play?#code/C4TwDgpgBAQgTgQwHYBMA8AVANFAmgPigF4oMoAyKAbygH1aAjRVALjwF8BYAKB9EigAxAPbDisZuiQBXALYMIcHAHIAEhAA2G4cvw8+4aAFEAHsEQBjYBkyESZCGYioAzhOToAlkgBmiqACCONJIANZIwgDuSIQA-IFQbEgQAG6K+tw+IVaewkhQwBAuwAAUCGym5ghWNiLC+ACU1BlcvNyFxSUAjA1AA

【问题讨论】:

  • 据我所知,没有办法在交叉点上分配任意类型的操作(根据microsoft/TypeScript#38039,并且由于Foo extends Brand&lt;Foo, unknown&gt;,没有原则性的方法可以告诉编译器你不想要Foo 退出该检查。撤消交集并不简单。如果 T 是非原始类型,您可以使用 Omit 或其他东西;否则我想您可以做一些非常笨拙的事情。我会调查一下但我的猜测是,任何解决方案都将是一个脆弱的解决方法。
  • 好的,看看this。我的建议是重构你的Brand&lt;T, Y&gt; 定义,这样你就可以退出T。如果它真的只是为了品牌,那么这样做应该没有问题(除非你不能触及定义)。否则,您可以尝试在我的其他代码中执行类似操作,但它非常脆弱;您需要预测可能的T 不适用于Omit。让我知道这一切对你来说是否有意义,我可以写一个答案。否则,让我知道我错过了什么。祝你好运!

标签: typescript typescript-generics


【解决方案1】:

如果您确定__brand 不会与任何其他对象发生冲突,您可以尝试...

type ExtractT<T> = T extends { __brand: unknown } ? Omit<T, '__brand'> : never;
var x: ExtractT<Foo> = 1; // works

【讨论】:

    猜你喜欢
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多