使用“静态”和“具体”泛型类型

时间:2017-11-29 19:33:48

标签: typescript typescript1.8

所以,我想传递一个“类型”来处理,以及一个对该类型的具体值进行操作的函数。

我希望有一个不那么冗长的方法,但我不确定。

我发现你可以说typeof MyClass表示“静态”类型,而MyClass只是具体类型。

以下是我想要调用的函数示例:

function SomeFunction<TStatic, TConcrete, TKey>(
   type: TStatic,
   keyGetter: (value: TConcrete) => TKey
): (key: TKey) => TConcrete
   ...

调用它看起来像:

Module.SomeFunction<typeof SomeType, SomeType, string>(SomeType, value => value.SomeText);

如果没有长类型列表,则无法推断该值为SomeType,但如果我明确指定它,我可以将其简化为此并仍然获得正确的类型:

Module.SomeFunction(SomeType, (value: SomeType) => value.SomeText);

当我知道我有Text属性时,有一个版本的函数更简单:

function SomeFunction2<TStatic, TConcrete extends { Text: string }>(
  type: TStatic
): (key: string) => TConcrete {
   return Module.SomeFunction<TStatic, TConcrete, string>(type, value => value.Text);
}

但是使用它,它无法推断出TConcrete的类型,所以如果我希望这些类型是正确的,我最终会将其作为最简单的版本:

Module.SomeFunction2<typeof SomeType, SomeType>(SomeType);

我真的想说的就是这个,它可能在C#中运行良好:

Module.SomeFunction(SomeType, value => value.Text);
Module.SomeFunction2(SomeType);

我可以以某种方式摆脱TStaticTConcrete之间的这种区别,或做其他任何可以让我进一步简化这一点的事情吗?

1 个答案:

答案 0 :(得分:1)

据我了解,TStaticTConcrete不是独立的。传递类型名称时传递的内容实际上是类的构造函数。我们可以为构造函数指定签名而不是TStatic,这将有助于编译器更好地推断出类型。

function SomeFunction<TConcrete, TKey>(
    type: new (...params: any[]) => TConcrete,
    keyGetter: (value: TConcrete) => TKey
): (key: TKey) => TConcrete {
    // ...
}


SomeFunction(SomeType, (value) => value.SomeText); // Works fine 

注意:我测试了最新的打字稿,我看到问题标记为1.8,它应该是一样的,但是如果它适合你,请在评论中告诉我。