microsoft / microsoft/TypeScript
Proposal: Overload Function.bind for when no argArray is provided.
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.4k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 117
説明
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'.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、Function.bind の型定義と、その型の動作をカバーするテストを探します。thisArg のみを指定する呼び出し用に提案されたオーバーロードを追加しつつ、既存の可変長引数シグネチャを維持し、その後、例が互換性のない callback 型を拒否することと、既存の bind のケースが引き続きパスすることを確認します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- 機能追加
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 35/100