microsoft / microsoft/TypeScript

Proposal: Overload Function.bind for when no argArray is provided.

Ouverte
#22,669 3 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

In Discussion Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.4k
Merge moyen
1 j 19 h
PR mergées (30 j)
117

Description

Background

Currently the Function.bind type definition defines only one signature:

bind(this: Function, thisArg: any, ...argArray: any[]): any;

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:

bind<T extends Function>(this: T, thisArg: any): T;
bind(this: Function, thisArg: any, ...argArray: any[]): any;

Example

To use a real world example on how this improves TypeScript I'll pull something from a personal project.

Types used:

type SocketMsg = Guess | StateMsg;
type ChannelCallback<T> = (payload: T, ref: Ref, joinRef: Ref) => any;

export class Channel<T> {
  // ...
  on(event: ChannelEvent, callback: ChannelCallback<T>): void;
  // ...
}
export default class GuessView extends Component<GuessProps, GuessState> {
  channel: Channel<SocketMsg>;

  connectSocket() {
    ...
    this.channel.on("guess", this.gameGuess.bind(this));
  }

  gameGuess(guess: Guess) {
    let newState = Object.assign({}, this.state);
    newState.guesses.push(guess);
    this.setState(newState);
  }
}

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'.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par localiser la définition de type de Function.bind et les tests couvrant son comportement de type. Ajoutez la surcharge proposée pour les appels qui ne fournissent que thisArg, tout en conservant la signature variadique existante, puis vérifiez que l’exemple rejette un type de callback incompatible et que les cas existants de bind passent toujours.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.