具有多个类型参数的通用推断类型

时间:2017-12-01 15:04:49

标签: typescript generics typescript2.0

我正在尝试设置一个泛型,其中参数是另一个对象的键。当两个类型都是函数的参数时,我可以使用extends keyof来完成此操作。

但是,当提供键列表的类型不是参数时,只是泛型类型,typescript需要设置两种泛型类型。

请考虑以下代码:

interface Bar {
  z: string;
  t: number;
}

declare function foo1<T extends keyof Bar>(x: T)
let t1 = foo1('z');

declare function foo2<K, T extends keyof K>(x: T)
let t2 = foo2<Bar>('t');

declare function foo3<T>(x: T)
let t3 = foo3<keyof Bar>('t');

Playground link

函数foo2失败,因为未指定第二个类型T。但是我觉得TS应该能够在没有明确的第二种类型的情况下推断出正确的输入。

foo3是我的解决方法,但使用起来不太好,是否可以让打字稿执行此推理,或者这是否是TS团队的功能请求/错误报告?

2 个答案:

答案 0 :(得分:2)

您与SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_track_order_map_fragment); mapFragment.getMapAsync(this); 关系密切。以下是使其发挥作用的原因。

<fragment
    android:id="@+id/fragment_track_order_map_fragment"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

您可以为一个类型指定一个(在这种情况下为foo2的类型),而不是期望一个新的泛型类型参数。

还可以直接将参数类型分配给给定通用类型declare function foo2<T, K = keyof T>(x: K) let t2 = foo2<Bar>('t'); 的{​​{1}}。

T

答案 1 :(得分:0)

How to do a Case Insensitive search on Azure DocumentDb?处已经有一个关于部分推断类型参数(不使用默认值)的明显建议。现在,你不能这样做。相反,在这种情况下,我会给你一个Microsoft/TypeScript#14400workaround that I often suggest函数。

declare function curriedFoo<B>(): <T extends keyof B>(x: T)=>any;
let t4 = curriedFoo<Bar>()('t'); // okay

无参数函数curriedFoo()采用类型参数B(除了键之外我不能使用K,抱歉),并返回类型为你的函数真的想要,缩小到仅接受T extends keyof B参数(这里是我想要使用K的地方,但没关系)。

这有点笨拙,但它完成了工作。希望有所帮助;祝你好运!