microsoft / microsoft/TypeScript
Stricter Assignability Checks for Overloaded Functions
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem verlinkten TypeScript Playground repro und dem im Beispiel beschriebenen Überladungs- und Zuweisbarkeitsverhalten. Als abgeschlossen gilt die Arbeit, wenn der Compiler die vorgeschlagenen Prüfungen durchführt und den unsicheren Aufruf meldet, während das angegebene Laufzeitverhalten erhalten bleibt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 35/100