You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
the types 'T' and (anything else) have no overlap #32768
No error; check returns true if given num (or an alias of it), and false otherwise.
Actual behavior:
index.ts:3:10 - error TS2367: This condition will always return 'false' since the types 'T' and '1' have no overlap.
3 return x === num;
~~~~~~~~~
Found 1 error.
I observed this in a slightly more complex case but with the same idea:
constisNum=(v: unknown)=>{if(typeofv!=='number')thrownewError('Not a number');returnv;};constisString=(v: unknown)=>{if(typeofv!=='string')thrownewError('Not a string');returnv;};functionmakeExampleValue<T>(validator: (v: unknown)=>T): T{if(parser===isNum)return42;if(parser===isString)return'something';thrownewError('unknown type');}
I'm considering restructuring to avoid the need for what is effectively a switch in a monolith function, but the reported error is incorrect in any case.
As for why you need to explicitly add extends unknown for your equality check to work, even though extends unknown should be implicit
Without an explicit constraint I think the default constraint used is the empty object type (if you do extends {} you get the same result as with no constraint).
constconstraint=getConstraintOfType(<TypeVariable>source);if(!constraint||(source.flags&TypeFlags.TypeParameter&&constraint.flags&TypeFlags.Any)){// A type variable with no constraint is not related to the non-primitive object type.if(result=isRelatedTo(emptyObjectType,extractTypesOfKind(target,~TypeFlags.NonPrimitive))){errorInfo=saveErrorInfo;returnresult;}}
I'm wondering if this was just a missed case in #30637?
Ryan Cavanaugh (@RyanCavanaugh)number is not comparable to T, and T isn't comparable to number (because unknown - T's constraint - isn't comparable to number).
We have another issue open about this, but if you tried to "fix" it, you might end up with weird behavior where two unrelated type parameters T and U can be checked for equality. While it's not unsound, it allows questionable code.
It's actually the other way around - number is comparable to unknown. Comparability is still a unidirectional relationship that we happen to apply in two directions.
and the example works ifT is explicit constrained to unknown (which should (???) be a no-op by my understanding).
I would consider that a bug, and I've opened #32814 to track it. I would guess it's likely either a bug in our getApparentType logic, or in the way we get implicit constraints, or we have some weird special unknown type we're not doing the right thing with.
Yeah I knew the design had changed, but I wasn't sure if a case had been missed. That code looked related, though tbh, I'm not really sure what's going on.
Activity
davidje13 commentedon Aug 8, 2019
My use-case approximates to the following:
I'm considering restructuring to avoid the need for what is effectively a switch in a monolith function, but the reported error is incorrect in any case.
AnyhowStep commentedon Aug 8, 2019
T extends unknown?davidje13 commentedon Aug 9, 2019
AnyhowStep that works, so I guess I'm confused why
<T>and<T extends unknown>are different (i.e. why isn'textends unknownthe default assumption?)AnyhowStep commentedon Aug 9, 2019
If it can't infer
T, it should default tounknownin your case (since you didn't specify a constraint type).As for why you need to explicitly add
extends unknownfor your equality check to work, even thoughextends unknownshould be implicit...¯\(ツ)/¯
RyanCavanaugh commentedon Aug 9, 2019
Daniel Rosenwasser (@DanielRosenwasser) what's the reasoning behind the current comparability rules with type parameters?
jack-williams commentedon Aug 9, 2019
AnyhowStep
Without an explicit constraint I think the default constraint used is the empty object type (if you do
extends {}you get the same result as with no constraint).I'm wondering if this was just a missed case in #30637?
DanielRosenwasser commentedon Aug 9, 2019
Ryan Cavanaugh (@RyanCavanaugh)
numberis not comparable toT, andTisn't comparable tonumber(becauseunknown-T's constraint - isn't comparable tonumber).We have another issue open about this, but if you tried to "fix" it, you might end up with weird behavior where two unrelated type parameters
TandUcan be checked for equality. While it's not unsound, it allows questionable code.RyanCavanaugh commentedon Aug 12, 2019
Daniel Rosenwasser (@DanielRosenwasser)
unknownis comparable tonumber, and the example works ifTis explicit constrained tounknown(which should (???) be a no-op by my understanding).DanielRosenwasser commentedon Aug 12, 2019
It's actually the other way around -
numberis comparable tounknown. Comparability is still a unidirectional relationship that we happen to apply in two directions.I would consider that a bug, and I've opened #32814 to track it. I would guess it's likely either a bug in our
getApparentTypelogic, or in the way we get implicit constraints, or we have some weird specialunknowntype we're not doing the right thing with.RyanCavanaugh commentedon Aug 12, 2019
We're going to track this at #32814 for clarity
typescript-bot commentedon Aug 15, 2019
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
weswigham commentedon Aug 15, 2019
FYI, the default base constraint is
unknownnowadays - we swapped a few releases ago.jack-williams commentedon Aug 15, 2019
Yeah I knew the design had changed, but I wasn't sure if a case had been missed. That code looked related, though tbh, I'm not really sure what's going on.