TypeScript Version: 3.x, 4.0.0-beta, nightly
Search Terms: dummy fake overload infer
Code
classFieldEvent<TextendsField>{constructor(readonlyfield: T,readonlymessage: string){}}classField{listen<TextendsFieldEvent<Field>>(type: new(...args: any[])=>T,listener: (event: T)=>void): void{}}classBeforeSetEvent<Textendsnumber|string>extendsFieldEvent<ValueField<T>>{constructor(field: ValueField<T>,publicnewValue: T){super(field,"");}}classAfterSetEvent<Textendsnumber|string>extendsFieldEvent<ValueField<T>>{constructor(field: ValueField<T>,readonlyoldValue: T){super(field,"");}}classValueField<Textendsnumber|string>extendsField{constructor(publicvalue: 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<UextendsFieldEvent<Field>>(type: new(...args: any[])=>U,listener: (event: U)=>void): void{super.listen(type,listener);}}letfield=newValueField(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.
TypeScript Version: 3.x, 4.0.0-beta, nightly
Search Terms: dummy fake overload infer
Code
Expected behavior:
eventto be better inferred thanany.Actual behavior:
eventinferred asany.But if we uncomment the 2 overloads, then
eventis correctly inferred:What's surprising (so the reason I consider it as a bug):
Note that if we replace
(arg: this)by()or another type, then: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.