unsplash / intlc

Compile ICU messages into code. Supports TypeScript and JSX. No runtime.
MIT License
56 stars 3 forks source link

Prevent tsc from narrowing nested switch statements #133

Closed samhh closed 2 years ago

samhh commented 2 years ago

Fixes #111.

Indiscriminately wraps all switch statement conditions in an IIFE for the simplest possible solution. This'll slightly worsen bundling performance because I doubt Terser et al will be willing to remove the IIFE.

samhh commented 2 years ago

NB if anyone can figure out an inline type-level solution that'd be ideal!

OliverJAsh commented 2 years ago

NB if anyone can figure out an inline type-level solution that'd be ideal!

This? https://github.com/unsplash/intlc/issues/111#issuecomment-1106525729

samhh commented 2 years ago

This? #111 (comment)

Potentially, but where does A come from, particularly if we'd like to avoid creating a closure? I think the only reference to our types that we have is typeof x.<arg> and TypeScript follows that.

samhh commented 2 years ago

Oh snap, if you do the as typeof on the first condition that actually fixes it for the second one: https://www.typescriptlang.org/play?ssl=9&ssc=2&pln=1&pc=1#code/MYewdgzgLgBAZjAvDAFADwFwwN4wJ5YDkAhoTAD4yEBGZAvgJRIB8OAUDDBAO4CWUwABao0AOjwxiEGFDwAHAKYgEYvE2wdOMYFIVVSWDVq09+QkePWbjnHRD01Chuta0vj7mC7pA

I prefer that for the bundling implications, gonna replace this PR. :smile:

OliverJAsh commented 2 years ago

if we'd like to avoid creating a closure

Not sure if you consider this a closure but we could do something like this:

(x: { y: 'a1' | 'a2' }) => {
  type A = typeof x.a;
  switch (x.y as A) {
    case 'a1': {
      // narrows
      switch (x.y as A) {
        case 'a2': {
        } // no error
      }
    }
  }
};
OliverJAsh commented 2 years ago

Oh snap, if you do the as typeof on the first condition that actually fixes it for the second one:

WTF lol

samhh commented 2 years ago

Not sure if you consider this a closure

I do. At the moment the codegen always produces a lambda with an implicit return, which keeps things very simple, all on one line and without any redundancy.

So, it'd be doable, but the code would be a bunch more complex.

WTF lol

:laughing: