-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
TS2.4 compile error with derived type assignment #16790
Comments
This is related to using workarounds for static polymorphic this as described in #5863 |
You left out the code that would tell us the answer
|
It's in the build that I linked. Seems to be an issue with module resolution - but it worked before 2.4 |
You'll need to provide a repro that actually demonstrates the problem. Three empty class declarations is not sufficient. |
@RyanCavanaugh You can reproduce by cloning https://github.com/types/sequelize and running the commands from the failed build ( |
oh my god....i dont know what happend.my project can not run..because of something package update typescript [email protected] by semantics version... |
Almost all of these errors are actual errors in how people typed things. It may not be your code directly, but it maybe some sort of upstream system. Before 2.4, the type system was a bit lazy when it came to assessing the assignability of generics. Likely somewhere Either way there is a problem in the code that likely needs to be addressed, because there is some sort of unsound type handling going on. Of course you can 🙈 🙉 🙊 and turn on |
@kitsonk can you explain the wrong typing in this error?
if |
@RyanCavanaugh I'm trying to update the Sequelize types to 2.4 but that is blocked by this issue. Does the public repo work as a repro case for you? |
@lumaxis we generally don't have time to investigate large external repositories to diagnose user code unless there's a crash or other clear evidence of a TS bug. If there's something blocking you from creating a self-contained minimal repro I can help you with some tips if needed. |
@RyanCavanaugh Hi Ryan - I created a self-contained repository with the mentioned packages above to demonstrate the issue. It is here: https://github.com/mmitchellgarcia/Derived-Type-Assignment-Error. If you run
|
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
@mhegazy I don't feel like this issue has been addressed, it's waiting for feedback from the team. Does @mmitchellgarcia example work as a repro for you? |
Here is a simpler repro: interface B {
increment(fields: Partial<B>): Promise<B>;
}
interface D {
increment(fields: "foo" | Partial<D>): Promise<D>;
other: string;
}
declare var b: B;
declare var d: D;
b = d; // Error: D is not assignable to B As work around for now, sequelize types can be changed to have increment(fields: keyof this | (keyof this)[], options?: IncrementDecrementOptions): Promise<this>;
increment(fields: Partial<this>, options?: IncrementDecrementOptions): Promise<this>; |
Here's an even smaller repro: interface B {
increment(fields: B): B;
}
interface D extends B {
increment(fields: "foo" | D): D;
other: string;
} |
This error is technically correct; it's easy to construct an example that shows class B {
increment(fields: B): B {
return fields;
}
}
class D {
increment(fields: "foo" | D): D {
if (typeof fields === "string") {
return this
}
else {
console.log(fields.other) // Runtime error if `fields: Base`
return fields;
}
}
other: string = "default";
}
var b: B = new D();
b.increment(new B()) // b is allowed here, but will be passed to D.increment However, it seems like the unsafe relation is desired and used to work. I'll see why it stopped working. |
Yeah, that example seems like it should error. But the Sequelize example that uses the polymorphic |
The reason that @mhegazy's example doesn't fail in 2.3 is that "foo" is assignable to I'll take a look at the Sequelize example to see how it fails in 2.3 vs 2.4+. |
@felixfbecker Actually they have the same cause. Error on inheritance and assignabilityinterface B {
increment(fields: B): B;
}
interface D extends B { // error here
increment(fields: D | "foo"): D;
other: string;
}
declare var b: B
declare var d: D
b = d // error here Error only on assignabilityinterface B {
increment(fields: this): this;
}
interface D extends B { // no error here
increment(fields: this | "foo"): this;
other: string;
}
declare var b: B
declare var d: D
b = d // error here Notice that in the class-based example I gave above, even if you change the I don't know Sequelize's code, but I suspect that it never does anything like let m: Model = new MainModel();
m.set(new AssociatedModel()); It is probably careful to never mix different subclasses, so probably avoids runtime errors. The crux of the problem is that probably is not provably, and the compiler started complaining about provability in one lone place in Typescript 2.4. |
I tried relaxing the weak-type check for unions, although I'm not sure this is the right solution. This allows the small example to succeed but not the Sequelize example. I'll have to investigate further. |
I got Sequelize to work by turning off the weak-type check for unions both in covariant and contravariant relations. After discussing it again with @mhegazy, we decided that the weak type check is working as intended, however. Weak type errors popped up lots of places in 2.4, and this error is not fundamentally different from the others. It's just obscured under several layers of complexity. Since Sequelize likely is safe to use, even though it's unsound, I think the correct workaround is the one proposed [here -- split the offending |
TypeScript Version: 2.4.1
Code
Expected behavior:
compile without error
Actual behavior:
The text was updated successfully, but these errors were encountered: