Proposal: Overload Function.bind for when no argArray is provided. #22669
Description
Activity
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensus
on Mar 19, 2018 I'm in favour, I have been adding similar interface augmentation into my projects for ages.
I have to point out though that since
bindis defined oninterface Function,extends Functionis extraneous.thistype will always extendFunction.FWIW, with TypeScript 2.8, it is possible to construct a proper type for
bindvia conditional types, albeit with a limit on a maximum number of arguments: https://gist.github.com/lierdakil/92256af3fae9fea9cf43688d0b98edcb#file-lib-d-ts -- here it works for functions with up to 10 arguments and after that falls back to...args: any[]. The limit of 10 is arbitrary and can be easily changed.P.S. I should note, it'd be possible to avoid horribleness above if we had variadic generic types.
Echoing Nikolay Yakimov (@lierdakil):
bind(this: Function, thisArg: any): this;would indeed accomplish the task at hand, but it still violates type safety insofar as there is nothing that checks that the function'sthisargument is of the type ofthisArg. That being said, it would be much safer than the current declaration which is an easy 'gotcha' when usingbind, as with @teaearlgraycold's original example. I've seen it suggested to always choose lambda closures overbindinvocations for this reason. Obviously, that's not ideal since it causes the parameter declaration to bleed into places it doesn't need to be, making signature refactoring more difficult.A top-level function would give you far better safety in this regard:
function getBound<T extends {[K1 in K]: Function}, K extends keyof T>(obj: T, member: K): T[K] { return obj[member].bind(obj); }
There's no good way to declare the
bindfunction to provide the same safety as my example function above unless TypeScript somehow captured the type from a property access resulting in a function, and it's probably not worth the trouble.I would love to get this implemented, but the automated PR checks said unless this issue is signed off and added to the next version's requested changes, my PR wouldn't get merged.
This is particularly annoying when leveraging Storybook's CSF syntax as they recommend using
.bind({})to create many stories.Ryan Cavanaugh (@RyanCavanaugh) let me know if this is something I can work on.
Background
Currently the
Function.bindtype definition defines only one signature:This destroys typing information on the bound function. Given difficulties in generating a new type for the bound function (the number of arguments has changed) this makes sense. However, it's very common to bind functions without using the
argArrayargument tobind. In this case a better solution can be made.Proposal
I propose that
bindbe overloaded with a second signature:Example
To use a real world example on how this improves TypeScript I'll pull something from a personal project.
Types used:
Under the current
bindsignature a change togameGuesssuch that it accepts a different type would produce no error:But with
bindutilizing a special definition for the case of only using thethisArgargument - the above example would produce an error.