I have an interface with a generic field, sort of like
interface HasVal<T> {
val: T
}
I want to create a function like get_val which accepts any HasVal implementer and returns it's val:
function get_val<T, Hv extends HasVal<T>>(hv: Hv): T {
return hv.val
}
This doesn't work, because T doesn't get narrowed for some reason:
class MyVal {
val = "hello world!"
}
let u = get_val(new MyVal());
// type of u is unknown :(
Is there a type signature for get_val that will return the proper type without requiring the caller to specify it?
The problem with
is that generic constraints are not used as inference sites for other generic type arguments. (Such a feature was suggested at microsoft/TypeScript#7234 but eventually declined in favor of other techniques.) So while
Hvcan be inferred from thehvargument,Tcannot be inferred from theHv extends HasVal<T>constraint. There's pretty much nowhere from whichTcan be inferred, so it falls back to the implicitunknownconstraint, and you get the undesirable behavior.Given this example, I'd be inclined to just remove the
Hvtype parameter entirely. If you want to inferTfrom an input of typeHasVal<T>, tell the compiler thathvis of typeHasVal<T>directly, not indirectly via a constraint:And now things behave as desired:
Tis inferred asstringbecause aMyValinstance is seen as a validHasVal<string>.Playground link to code