-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong type inference, returns the base class type instead of the child class type #57286
Comments
I don't know why you've reported two things in one issue, but in all of your examples, your child classes seem to be structurally identical to your base classes. Technically that means TS is within its rights to use the names interchangeably. Maybe for your examples you should add some distinguishing structure to your child classes just to avoid any confusion? "Bug 1" is a widening of a generic to its constraint when indexing with a specific key. This is essentially the same thing as #33181, or at least both of these are caused by such widening. This isn't necessarily a bug: such a widening isn't incorrect in your example; it's just not as specific as you'd like. I'd also like to see this changed to be more generic, but I'd phrase it as a feature request and not a bug. |
Done.
It is a little infuriating to see that the issues I spent days trying to find workarounds for are known for 4-5 years...
I was wondering how So the "widening" is forcing us to explicitly specify the generic function return type, which in turn can be error prone. {
class Base {
get self(): Base { return this; }
}
class Child extends Base {
override get self(): Child { return this; }
child = true;
}
function foo<T extends Base>(e: T): T["self"] {
//let self = e.self;
let base = new Base();
return base;
}
let ret = foo(new Child());
let b = new Base();
let c1 = b as Child; // ok
let c2: Child = b; // nok
} |
Pointing out what I agree to be the problem: class BaseClass<V> {
protected fake(): V { throw new Error("") }
}
class Klass<V> extends BaseClass<V>{
child = true;
}
// Replace BaseClass<V> with BaseClass<unknown> to un-repro
type Constructor<V, P extends BaseClass<V>> = new () => P;
type inferTest<V, T> = T extends Constructor<V, infer P> ? P :never;
type U = inferTest<number, Constructor<number, Klass<number>>>
declare let m: U;
// Should be OK, m: Klass
m.child; |
π Search Terms
None
π Version & Regression Information
β― Playground Link
Playground Link
π» Code
π Actual behavior
Bug1: It seems that when calling methods in generic function
foo<T extends Base>(t: T)
:Bug2: For type inference, it seems that adding a generic parameters confuses TS.
π Expected behavior
Cf code.
Additional information about the issue
Related to issue #57102
The text was updated successfully, but these errors were encountered: