microsoft / microsoft/TypeScript
Need a dummy overload to improve inference
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.3k
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 132
Descripción
TypeScript Version: 3.x, 4.0.0-beta, nightly
Search Terms: dummy fake overload infer
Code
class FieldEvent<T extends Field> {
constructor(readonly field: T, readonly message: string) { }
}
class Field {
listen<T extends FieldEvent<Field>>(type: new (...args: any[]) => T, listener: (event: T) => void): void { }
}
class BeforeSetEvent<T extends number | string> extends FieldEvent<ValueField<T>> {
constructor(field: ValueField<T>, public newValue: T) { super(field, ""); }
}
class AfterSetEvent<T extends number | string> extends FieldEvent<ValueField<T>> {
constructor(field: ValueField<T>, readonly oldValue: T) { super(field, ""); }
}
class ValueField<T extends number | string> extends Field {
constructor(public value: T) { super(); }
// listen<U extends FieldEvent<Field>>(type: new (arg: this) => U, listener: (event: U) => void): void;
// listen<U extends FieldEvent<Field>>(type: new (...args: any[]) => U, listener: (event: U) => void): void;
listen<U extends FieldEvent<Field>>(type: new (...args: any[]) => U, listener: (event: U) => void): void {
super.listen(type, listener);
}
}
let field = new ValueField(0);
field.listen(FieldEvent, (event) => event.field); // event: FieldEvent<any>
field.listen(BeforeSetEvent, (event) => { event.field; event.newValue; }); // event: BeforeSetEvent<any>
field.listen(AfterSetEvent, (event) => { event.field; event.oldValue; }); // event: AfterSetEvent<any>
Expected behavior:
event to be better inferred than any.
Actual behavior:
event inferred as any.
But if we uncomment the 2 overloads, then event is correctly inferred:
field.listen(FieldEvent, (event) => event.field); // event: FieldEvent<ValueField<0>>
field.listen(BeforeSetEvent, (event) => { event.field; event.newValue; }); // event: BeforeSetEvent<0>
field.listen(AfterSetEvent, (event) => { event.field; event.oldValue; }); // event: AfterSetEvent<0>
What's surprising (so the reason I consider it as a bug):
- The 1st overload doesn't match any signature.
- But it influences the way the other overload is inferred.
Note that if we replace (arg: this) by () or another type, then:
field.listen(FieldEvent, (event) => event.field); // event: FieldEvent<Field>
field.listen(BeforeSetEvent, (event) => { event.field; event.newValue; }); // event: BeforeSetEvent<string | number>
field.listen(AfterSetEvent, (event) => { event.field; event.oldValue; }); // event: AfterSetEvent<string | number>
Playground Link: Playground Link
Related Issues: I first posted #36226 but was not able to solve my issue, until I found the (arg: this) trick.
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
Empieza reproduciendo el ejemplo en el TypeScript Playground enlazado y compara la inferencia con y sin las dos sobrecargas. Rastrea el comportamiento de la inferencia genérica y de la resolución de sobrecargas del compilador para las llamadas a listen; el trabajo estará terminado cuando los callbacks infieran FieldEvent, BeforeSetEvent y AfterSetEvent con los tipos concretos relevantes, sin las sobrecargas dummy.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- typescript
- Área
- compilers
- Tipo de issue
- Error
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 25/100