Reputation: 68
Is there any way in Typescript to capture a generic class without its type parameter? I'm essentially trying to make a procedural style map function that operates on collection classes in my program like
interface Collection<T> {
...
}
function map<T, U, V extends Collection>(collection:V<T>, fn:(e:T) => U):V<U> {
....
}
but this doesn't work since the compiler wants me to put a type parameter on the Collection in map's generic list.
Essentially I want the type checker to know that if I call it on a List<T>
, I get back a List<U>
; call it on a Set<T>
, I get a Set<U>
; etc. Is this possible?
Thanks
Upvotes: 0
Views: 1106
Reputation: 251242
Here is my take on this...
function map<T, U, V extends Collection<any>>(collection: V, fn:(e:T) => U) : Collection<U> {
return null;
}
Compromise one: You can't re-use the type T
in V extends Collection<any>
. Ideally, you would have used T
not any
.
Compromise two: We are returning the less specific Collection<U>
from the function. Ideally, you accept a general type and return a specific one, so this is a compromise.
No compromise version. You need an in type and an out type and you need a generic class so you can re-use the class types within the method type arguments:
class Mapper<T, U> {
map<TIn extends Collection<T>, TOut extends Collection<U>>(collection: TIn, fn:(e:T) => U) : TOut {
return null;
}
}
Upvotes: 1