简体   繁体   English

带有泛型的 TypeScript 接口函数类型

[英]TypeScript Interface function type with generics

I found the following code byte in an open source repository recently:我最近在一个开源存储库中发现了以下代码字节:

interface Use<I, C = context<I>> { 
   <O>(fn: avvio.Plugin<O, I>, options?: O): C; 
} 

Simplified as:简化为:

interface F<A> {
  <B>(foo: A, bar: B): A;
}

How would I go about invoking the B generic?我将如何调用B泛型?

I'm struggling to find an example usage of it and I can't make sense of it even in the TS Playground.我正在努力寻找它的示例用法,即使在 TS Playground 中我也无法理解它。 I put this code in a playground you can view here .我把这段代码放在一个操场上,你可以在这里查看。

It's an interface for a function that take's a generic parameter.它是一个接受泛型参数的函数的接口。 Here is an example:下面是一个例子:

const funcTwo: F<string> = <T>(foo: string, bar: T) => {
  return `${foo} ${bar}`;
}

console.log(funcTwo('Hello', 7));

UPDATE: Adding a practical example that may show why it would be useful.更新:添加一个实际示例,可以说明它为什么有用。 It can be hard to come up with an example with no context but this is my best attempt without thinking too hard:很难想出一个没有上下文的例子,但这是我最好的尝试,不用考虑太多:

class UniqueCounter<T> {

  private underlyingSet = new Set<T>();

  constructor(
    private hashingFunc: <V>(value: V) => T,
  ) {

  }

  add<V>(thing: V) {
    const hash = this.hashingFunc(thing);
    this.underlyingSet.add(hash);
  }

  count() {
    return this.underlyingSet.size;
  }

}

This class attempts to count how many unique instances of something you have.这个类试图计算你有多少个独特的东西。 However, the default set uses === for objects and that isn't what I want.但是,默认集使用===对象,这不是我想要的。 Instead I have some kind of hashing algorithm for my particular objects.相反,我对我的特定对象有某种散列算法。 Although, in some cases I hash into a string and in other cases I hash into a number (the thing I hash into is T ).虽然,在某些情况下我散列成一个字符串,而在其他情况下我散列成一个数字(我散列成的东西是T )。

I can't add V to the class generics because then it would only be able to count one type of object.我不能将V添加到类泛型中,因为这样它就只能计算一种类型的对象。 Maybe I can hash Person and Employee and Equipment and Room by using some kind of unique ID I've assigned to all those classes.也许我可以使用我分配给所有这些类的某种唯一 ID 来散列PersonEmployee以及EquipmentRoom

I can't add T to the hash function's type arguments because I need to use T to define underlyingSet .我不能将T添加到散列函数的类型参数中,因为我需要使用T来定义underlyingSet

UPDATE2:更新2:

Ignore the previous update as it isn't relevant to the question at hand.忽略之前的更新,因为它与手头的问题无关。 The type you showed:您显示的类型:

interface F<A> {
  <B>(foo: A, bar: B): A;
}

is not equivalent to:不等同于:

interface F<A, B> {
  (foo: A, bar: B): A;
}

Let's pretend we had a hashing factory factory that could magically create hashing objects, but they could only hash into one type of key.假设我们有一个哈希工厂工厂,可以神奇地创建哈希对象,但它们只能哈希到一种类型的键中。 In other words, you could create a "hash anything to string" object or a "hash anything to number" object.换句话说,你可以创建一个“hash any to string”对象或一个“hash any to number”对象。 We could define the class as:我们可以将类定义为:

class HashingFactory<T> {

  createHasher<V>(): Hasher;

}

However, what would the return type be?但是,返回类型是什么? How would we define Hasher ?我们将如何定义Hasher If we define it as:如果我们将其定义为:

interface Hasher<K, V> {
  hash(value: V): K;
}

Then we are creating something that can only hash inputs of one type (eg it can only hash Employee into number).然后我们正在创建一些只能散列一种类型的输入的东西(例如,它只能将 Employee 散列成数字)。 But our magical hasher can hash any object into a number.但是我们神奇的散列器可以将任何对象散列成一个数字。 The proper interface would be:正确的界面是:

interface Hasher<K> {
  <V>hash(value: V): K;
}

Now we can properly represent an object that can turn Employee or Room or Person (or anything else) into a number.现在我们可以正确地表示一个可以将 Employee 或 Room 或 Person(或其他任何东西)转换为数字的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM