You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Proposal: Overload Function.bind for when no argArray is provided. #22669
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 argArray argument to bind. In this case a better solution can be made.
Proposal
I propose that bind be overloaded with a second signature:
Under the current bind signature a change to gameGuess such that it accepts a different type would produce no error:
connectSocket(){
...
this.channel.on("guess",this.gameGuess.bind(this));// Now being provided the wrong type of function}gameGuess(guess: number){// ...
But with bind utilizing a special definition for the case of only using the thisArg argument - the above example would produce an error.
Argument of type '(guess: number) => void' is not assignable to parameter of type 'ChannelCallback'. Types of parameters 'guess' and 'payload' are incompatible. Type 'SocketMsg' is not assignable to type 'number'. Type 'Guess' is not assignable to type 'number'.
I'm in favour, I have been adding similar interface augmentation into my projects for ages.
I have to point out though that since bind is defined on interface Function, extends Function is extraneous. this type will always extend Function.
FWIW, with TypeScript 2.8, it is possible to construct a proper type for bind via 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's this argument is of the type of thisArg. That being said, it would be much safer than the current declaration which is an easy 'gotcha' when using bind, as with @teaearlgraycold's original example. I've seen it suggested to always choose lambda closures over bind invocations 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:
There's no good way to declare the bind function 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.
Activity
lierdakil commentedon Apr 22, 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.
ts2do commentedon May 12, 2018
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:
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.kylemh commentedon Nov 2, 2020
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.