TypeScript does not throw an error at compile time for accessing an out-of-bounds index. Instead, it assumes that the value could be one of the types defined in the array (in this case, 1 or 2) or undefined.

TypeScript automatically infers the type of a value accessed from an array, even if that access is out of bounds. It assumes that the value could be one of the defined types or undefined, which can lead to confusion if you expect stricter enforcement of valid indices.

I just spent the last 2 hours trying to understand why I was getting a valid type from something that shouldn’t have been valid.

I think that the hate that JavaScript receives is well deserved, at least coming from Rust this is an absolute nightmare.

  • Feyd@programming.dev
    link
    fedilink
    arrow-up
    9
    ·
    1 month ago

    Your MyUnionType is defining an array (of any length) that only contains 1s and 2s. Setting values to [1,2] doesn’t narrow the type down to a tuple of 2. I’m not sure why you think it would, but feel free to explain your reasoning and maybe I can clarify your misunderstanding.

    In any case, it seems like you might be looking to use tuple types

    // this is an array that can contain 1s and 2s
    type ArrayOf1or2 = (1 | 2)[];
      
    
    // fine, because regardless of the length, it only contains 1s and 2s
    const ok1: ArrayOf1or2 = [1,1,1,2,2,2,1,2];
    
    // no good, because it can't have a 3
    const notok1: ArrayOf1or2 = [3];
    
    type Size2ArrayOf1sAnd2s = [(1 | 2), (1 | 2)];
    
    // has 2 so is fine
    const ok2: Size2ArrayOf1sAnd2s = [1,1];
    
    // has 1 so is not fine
    const notok2: Size2ArrayOf1sAnd2s = [1];
    
    // has 3 so is not fine
    const notok3: Size2ArrayOf1sAnd2s = [1,1,1];