microsoft / microsoft/TypeScript

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

Abierto
#22,669 3 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

In Discussion Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza localizando la definición de tipo de Function.bind y las pruebas que cubren su comportamiento de tipos. Añade la sobrecarga propuesta para las llamadas que proporcionan solo thisArg, conservando la firma variádica existente, y verifica después que el ejemplo rechaza un tipo de callback incompatible y que los casos existentes de bind siguen pasando.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.