-
Notifications
You must be signed in to change notification settings - Fork 12.8k
the types 'T' and 'typeof Class' have no overlap #44645
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
Comments
Not all comparisons are allowed; you can upcast either side to |
Thanks for replying. class Class {
}
class Class2 extends Class {
dummy = 0;
}
class Class3 {
}
function test<T extends typeof Class>(a:T):void{
if (a === Class) {} // it's okay
if (a === Class3) {} // it's okay
if (a === Class2) {} // it has problem
}
const test2:typeof Class = Class2; // it's okay
on this case. it has the same problem. |
That's sort of weird |
I've noticed another similar scenario where TS incorrectly asserts two types have no overlap and complains about their comparison: class Foo<T extends true> {
declare t: T
hasKind<kind extends true> (kind: kind) {
// This comparison appears to be unintentional because the types 'T' and 'kind' have no overlap.
return this.t === kind
}
} Amusingly in this case, Various manifestations of this error come up fairly often in my experience with generic parameters. This feels like the kind of message where TS should err on that side of caution, as it's not assignment- it's the language going out of its way to say "hey, this should never be possible, double check what you've done," which should really only be happening when there is certainty that the two types being compared are disjoint. |
Isn't that what's happening, though? |
TS should not prompt a developer to double check their logic based on a comparison between two values unless their types form a disjoint. In the example I've highlighted, the two values are guaranteed to be equal based on their types, yet TS complains they have no overlap. The more general case is if the parameters are unconstrained, i.e. TS has no information about their relationship to one another, you get the same message: class Foo<T> {
declare t: T
hasKind<kind>(kind: kind) {
// This comparison appears to be unintentional because the types 'T' and 'kind' have no overlap.
return this.t === kind
}
} Two |
I don't know what to say except that this is super, super intentional, and you really should get warned here. These are the kinds of checks where when we tighten them even slightly, we find huge numbers of actual bugs in real code. There are all kinds of mistakes you can make with |
But in the example I mentioned, there is absolutely no reason to believe that comparison is unintentional. Comparing two values of type I know often the That said, there is something that occurs when comparing two generics like this that results in TS making an overtly false claim that it has no evidence to make- i.e. that those types have no overlap. The only time this error should happen when comparing two generics like these are when both are constrained and the types of the two constraints form a disjoint. Other than that, it's both factually and practically wrong to assume the comparison is unintentional. I originally encountered this while writing a very uninteresting snippet of code to check if a Node type had a certain constraint kind, represented as a string. Despite both generics being constrained to the exact same type (in this case, the union |
Bug Report
π Search Terms
template class no overlap label:Bug
π Version & Regression Information
4.3.4 / 4.4.0-dev.20210617 / Nightly Playground
β― Playground Link
Playground Link
π» Code
π Actual behavior
ts2367 error.
a
can beClass
π Expected behavior
no error.
a
can beClass
The text was updated successfully, but these errors were encountered: