Closed
Description
TypeScript Version: 2.8.0-dev.20180211
Search Terms: enum literal intersection never
Code
type VerifyExtends<A, B extends A> = true
type VerifyMutuallyAssignable<A extends B, B extends C, C=A> = true
// string enum
enum Bug {
ant = "a",
bee = "b"
}
declare var witness: VerifyExtends<'a', Bug.ant> // okay, as expected
declare var witness: VerifyExtends<'b', Bug.ant> // error, as expected
declare var witness: VerifyMutuallyAssignable<Bug, Bug.ant | Bug.bee> // okay, as expected
declare var witness: VerifyMutuallyAssignable<Bug.ant, Bug.ant & 'a'> // okay, as expected
declare var witness: VerifyExtends<Bug, Bug.ant> // okay as expected
declare var witness: VerifyExtends<Bug & 'a', Bug.ant & 'a'> // error, not expected!!
declare var witness: VerifyMutuallyAssignable<Bug & 'a', never> // okay, not expected!!
// numeric enum
enum Pet {
cat = 0,
dog = 1
}
declare var witness: VerifyExtends<0, Pet.cat> // okay, as expected
declare var witness: VerifyExtends<1, Pet.cat> // error, as expected
declare var witness: VerifyMutuallyAssignable<Pet, Pet.cat | Pet.dog> // okay, as expected
declare var witness: VerifyMutuallyAssignable<Pet.cat, Pet.cat & 0> // okay, as expected
declare var witness: VerifyExtends<Pet, Pet.cat> // okay, as expected
declare var witness: VerifyExtends<Pet & 0, Pet.cat & 0> // error, not expected!!
declare var witness: VerifyMutuallyAssignable<Pet & 'a', never> // okay, not expected!!
Expected behavior:
I expect that Bug & 'a'
should reduce to Bug.ant
, or at least to Bug.ant | (Bug.bee & 'a')
.
Similarly, Pet & 0
should reduce to Pet.cat
, or at least to Pet.cat | (Pet.dog & 0)
.
Actual behavior:
Both Bug & 'a'
and Pet & 0
reduce to never
, which is bizarre to me. I was trying to solve a StackOverflow question and realized that my solution was narrowing literals to never
after a type guard. Something like:
declare function isBug(val: string): val is Bug
declare const a: "a"
if (isBug(a)) {
a // never?!
}
Thoughts?
Related Issues:
I'm really not finding any, after searching for an hour. A few near misses but nothing that seems particularly relevant.