简体   繁体   中英

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?

I'm struggling to find an example usage of it and I can't make sense of it even in the 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 ).

I can't add V to the class generics because then it would only be able to count one type of object. 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.

I can't add T to the hash function's type arguments because I need to use T to define underlyingSet .

UPDATE2:

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. We could define the class as:

class HashingFactory<T> {

  createHasher<V>(): Hasher;

}

However, what would the return type be? How would we define 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). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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