Search code examples
typescriptdestructuringfor-of-loop

When yielding a tuple, why does typescript union the types of both indices?


I am yielding an array with values of type [number, object] from a generator function and iterating over the function through for...of loop. When destructuring the values using for (const [k, v] of iterator()) the type of v is number | object. I expected it to have the type object- same as the one I used in the yield of the generator function.

I have created a demo of the problem I'm facing in the typescript REPL here

The problem is in line number 22 where typescript compiler complains about accessing a key that possibly does not exist after destructuring.

Why does typescript think that the destructured variables could be of either of the types?


Solution

  • This is not a generator issue. Array literals are usually widened to array types. If you use a as const assertion to preserve the tuple type it works as expected

    (function iterate() {
        function* iterator() {
            let id: number = 0;
            const value: {
                a: number,
                b: number
            } = {
                a: 1,
                b: 2
            };
            while (id < 10) {
                yield [
                    id,
                    value
                ] as const;
    
                id += 1;
            }
        }
    
        for (const [k, v] of iterator()) {
            console.log(k, v.a);
        }
    })();