microsoft / microsoft/TypeScript
Stricter Assignability Checks for Overloaded Functions
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.3k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 117
説明
Search Terms
function overload, assignability
Suggestion
When a function has overloads, each with a different number of arguments, subtle bugs can occur.
My suggestion is to have extra assignability checks for overloaded methods/functions.
When assigning A to B the algorithm should be,
- Is
Aassignable toBunder the existing assignability rules? - Is
Aan overloaded function/method?- If it is not, we are done.
- If it is, we need more checks,
- Does the assignable overload of
Ahave the same number of arguments asB?- If it does, we are done. (Right? Maybe?)
- If it doesn't, find all overloads of
Awith the same number of arguments asB- Is each overload assignable to
B? If it isn't, we have a compile-time error
- Is each overload assignable to
- Does the assignable overload of
Use Cases
Better type safety. I've been bitten by this behaviour regarding overloaded functions/methods in the past, with far more complicated examples. My general advice to people is to avoid overloads as much as possible/at all cost.
If this hole in the type system is fixed, I may not be so averse to overloads... Or I'll probably find something else to gripe about =x
Examples
The repro below has the following properties,
- Each overload has a different number of arguments
- Each overload has a different return type
function foo(a: number, b: symbol): string;
function foo(a: number): number;
function foo(a: number, b?: symbol): string|number {
if (b == undefined) {
return a;
} else {
return `a:${a},b:${String(b)}`;
}
}
function takesNumCallback(callback: (a: number, b: number) => number) {
const tmp = callback(1, 2);
if (typeof tmp != "number") {
throw new Error("wat");
}
console.log(1 / tmp);
}
//Allowed during compile-time
//But will throw an error during run-time
takesNumCallback(foo);
The problem here is that foo (a : number) : number is assignable to (a : number, b : number) => number, because TS assumes foo (a : number) : number will ignore the second argument (b).
However, TS is not considering the other overload that has two arguments and is expecting b : symbol.
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Well, it would break TS code for people currently using overloaded functions/methods unsafely.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
リンクされた TypeScript Playground の repro と、例で説明されている overload および assignability の挙動から始めてください。完了とは、コンパイラーが提案されたチェックを実行し、指定された実行時の挙動を維持したまま、安全でない呼び出しを報告することです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- 機能追加
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100