So, I would like to pass both a "type" to work on, as well as a function that operates on a concrete value of that type.
I'm hoping there's a less verbose way to do this, but I'm not sure.
I've figured out that you can say
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);
Module.SomeFunction(SomeType, value => value.Text);
Module.SomeFunction2(SomeType);
TStatic
TConcrete
From what I understand, TStatic
and TConcrete
are not independent. What you are passing when you pass the type name is actually the constructor for the class. We can specify the signature for the constructor instead of TStatic
this will help the compiler infer the types better.
function SomeFunction<TConcrete, TKey>(
type: new (...params: any[]) => TConcrete,
keyGetter: (value: TConcrete) => TKey
): (key: TKey) => TConcrete {
// ...
}
SomeFunction(SomeType, (value) => value.SomeText); // Works fine
Note: I tested on the latest typescript, I see the question is tagged with 1.8, it should work the same, but let me know in the comments if it works for you.