microsoft / microsoft/TypeScript
Stricter Assignability Checks for Overloaded Functions
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.3k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Descripción
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.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con el repro enlazado de TypeScript Playground y con el comportamiento de sobrecarga y asignabilidad descrito en el ejemplo. Se considera terminado cuando el compilador realiza las comprobaciones propuestas e informa de la llamada insegura, preservando el comportamiento de ejecución indicado.
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
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100