microsoft / microsoft/TypeScript
Stricter Assignability Checks for Overloaded Functions
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
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.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con il repro collegato di TypeScript Playground e con il comportamento di overload e assegnabilità descritto nell'esempio. Il lavoro è completato quando il compilatore esegue i controlli proposti e segnala la chiamata non sicura, preservando il comportamento a runtime indicato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100