Description
Currently apply
, call
and bind
each feature a thisArg
parameter typed as any
.
A comment by @amir-arad at gcanti/typelevel-ts#8 (comment) made me realize we might well be able to improve on that.
If we have a Foo
interface with methods e.g. bar()
on it, it should be clear what the constraint on thisArg
would be if we were to rebind said bar
method: Foo
. Unfortunately, bind
is defined on the Function
interface, which has no notion of Foo
.
To improve on this, I would suggest parameterizing the Function
interface to e.g. Function<T>
, where any methods on Foo
would automatically count as Function<Foo>
such that thisArg
for apply
, call
and bind
could then, through this T
, be constrained to Foo
. Any function not defined on such an interface would then get the Function.prototype
methods for Function<any>
.
Let's say instead of interface Foo
we would have an interface Bar<U extends Baz>
. In this instance, rather than binding its methods to Function<Bar<U>>
, it would be preferable to bind them to something like Function<Bar<any>>
(erase the generics) / Function<Bar<Baz>>
. After all, methods on interface Bar<U>
would support any Bar
, rather than its variants specific to any value of U
.
To prevent breaking changes, this new generic on Function
would have to provide a default value of any
to ensure existing Function
references would not suddenly be met with a "wrong number of generics" error.
There is another discussion on these three methods at #212, though it is focused more so on improving inference for their return types, rather than on constraining their parameters.