-
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
Some regression with union of classes in TS4.2 #43753
Comments
Here's a reduced version declare class LocalController<T, U> {
isLocal: true;
getProps(a: T, b: U): void;
}
declare class GlobalController<T, U> {
isLocal: false;
// N.B.: Parameter type order is reversed
getProps(a: U, b: T): void;
}
class FailWithTS42 extends LocalController<{ foo: any }, { bar: any }> { }
const p = new FailWithTS42();
// Fails
declare function createEnhancer1<T, U>(Wrapper: GlobalController<T, U> | LocalController<T, U>): void;
createEnhancer1(p);
// OK; this is the desired inference
createEnhancer1<{ foo: any }, { bar: any }>(p);
// OK
declare function createEnhancer2<T, U>(Wrapper: LocalController<T, U>): void;
createEnhancer2(p); The TL:DR is that we're getting tripped up here and collecting inferences from I don't know why this ever worked. |
cc @ahejlsberg for possible interest |
@weswigham hi! thank you for your work! i tried version The short version of the code from @RyanCavanaugh now really works without errors. But the original code still doesn't work. I tried to shorten my code a little more so that the error persists: declare class GlobalController<P, S> {
isLocal: false;
getProps(state: S, props: P): void;
}
declare class LocalController<P, S> {
isLocal: true;
getProps(props: P, state: S): void;
}
interface GlobalControllerClass<P, S> {
new(): GlobalController<P, S>;
}
interface LocalControllerClass<P, S> {
new(): LocalController<P, S>;
}
declare function createEnhancer<P, S>(Wrapper: GlobalControllerClass<P, S> | LocalControllerClass<P, S>): void;
class FailWithTS42 extends LocalController<{ baz: any }, { bar: any }> {}
createEnhancer(FailWithTS42); // fall since TS4.2 (4.1- works fine)
|
Looking at this again, something is just going wrong in a bad way, I don't think this is some "subtle" thing without a direct fix, unless I'm really missing something. Trimming the repro down more and poking at the adjacent cases which do work: declare function callme<T, U>(Wrapper: NotLocal<T, U> | Local<T, U>): void;
interface Local<T, U> {
isLocal: true;
a: T;
b: U;
}
interface NotLocal<T, U> {
isLocal: false;
// N.B.: Order of types is reversed here
a: U;
b: T;
}
// No example should error.
// Works
declare const direct_decl: Local<string, number>;
callme(direct_decl);
// Works
type LocalStringNumberAlias = Local<string, number>;
declare const type_alias: LocalStringNumberAlias;
callme(type_alias);
// Fails
interface LocalStringNumberInterface extends Local<string, number> { }
declare const interface_decl: LocalStringNumberInterface;
callme(interface_decl); That said we haven't seen other reports of this so I think this needs to be deprioritized in terms of scheduled work. @Andarist this seems very much up your alley in terms of investigations? |
is there a specific reason why structural inference doesn't check discriminates or why this worked pre-4.2? 🤔 |
I suspect this only worked by accident in 4.1-. As for why to not check for discriminants - 40% perf hit to material-ui (I remember this one) |
Bug Report
I apologize for the name of issue, I was not able to correctly formulate the problem.
🔎 Search Terms
4.2, regression, class, extends, union
🕗 Version & Regression Information
This changed between versions 4.1.5 and 4.2.2
(if we take dev then between versions 4.2.0-dev.20210209 and 4.2.0-insiders.20210210)
⏯ Playground Link
Playground link with relevant code
💻 Code
I apologize again, I have shortened the example as much as I can.
in the sandbox above the same code plus some workarounds that might suggest something
🙁 Actual behavior
createEnhancer(FailWithTS42)
in the last line shows the error:🙂 Expected behavior
I can call createEnhancer with class FailWithTS42
The text was updated successfully, but these errors were encountered: