#Bug in excluding type

1 messages · Page 1 of 1 (latest)

tropic ice
#
class Foo {

  counter = 0;
  get bar()  {
    return this.counter = (this.counter++ % 5) as 0|1|2|3|4|5;
  }

  baz() {
    if (this.bar === 0) {
      // something
    } else {
      switch(this.bar) {
        // TS2678: Type '0' is not comparable to type '1 | 5 | 2 | 3 | 4'.
        case 0: // Is a mistake and should be possible indeed
          console.log('');
      }
    }
  }
}```

Typescript is removing here 0 from the type, but since its gotten via a getter, it can vary
vale reef
#

you should just make bar() a function

tropic ice
#

okay but it knows its a getter lol

#

Bit of an oversight tbh

vale reef
#

but properties shouldn't change regardless

#

just because it is a function so the value can change may be different

#

doesn't mean it's logically sound for a getter to return a different value every time

tropic ice
#

I guess so, still hmm

vale reef
#

is there a reason doing bar() is that much of a crime?

ebon juniper
#

Well, let's say you extend a class coming from a third party library, it wouldn't be possible for TS to know what that getter is doing.

tropic ice
#

I mean what is the point of getters if they are not real invoked functions. Your right you shouldnt do this but in such a type safe lang as ts, it should see that this is not a prop but a method and there for treat it as one

vale reef
#

the thing is, it's much much more useful if you assume they don't change

vale reef
tropic ice
#

😅

vale reef
#

basically, it's not worth completely ruining narrowing for every single getter

#

just to make it more technically correct

tropic ice
#

I guess

#

its out of line what typescript does as normally its extremly technically correct in typing

ebon juniper
#

It's not

tropic ice
#

so odd here it isnt but i also get what your saying

ebon juniper
#

TS is never meant to be 100% correct.

vale reef
tropic ice
#

!close

#

Thanks btw 🙂

ebon juniper
#

There are lots of things in TS that are not sound, a very obvious one is arr[i], unless you turn on noUncheckedIndexAccess, TS always assumes it won't be undefined

#

Or stuffs like:

const nums: number[] = []

const numOrStrs: (number | string)[] = nums
numOrStrs.push('string')

nums // now contains a string despite still being number[]
#

Being sound is a non goal of TS, the goal is to improve productivity. Supporting these edge cases simply breaks too many features that ultimately results in worse productivity, so they aren't.