7

In one of my modules I use an optional tuple for a function result:

function ruleFromPosition(position): [string, number] | undefined;

and assign this to local vars in my unit tests:

let [ruleName, ruleIndex] = ruleFromPosition(position);

This results in the error:

Type must have a 'Symbol.iterator' method that returns an iterator.

I could re-write this statement as:

let [ruleName, ruleIndex] = ruleFromPosition(position)!;

, which compiles, but that disallows for nullable checks. What's the correct way to use the tuple?

1 Answer 1

3

This is not a TypeScript "problem". You just can't destructure undefined:

let [a, b,] = undefined;

BOOM: Uncaught TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

(see exploringjs, destructuring)

Since your function has the propability of returning undefined, TypeScript won't compile. You can:

Check for the return value

function ruleFromPosition(position): [string, number] | undefined {
    if (position > 1) return undefined;

    return ['1', 0];
}

const result = ruleFromPosition(1);

if (result) {
  let [ruleName, ruleIndex] = result;
}

Return an destructurable array

function ruleFromPosition(position): [string | undefined, number | undefined] {
    if (position > 1) return [undefined, undefined];

    return ['1', 0];
}

let [ruleName, ruleIndex] = ruleFromPosition(0);
Sign up to request clarification or add additional context in comments.

1 Comment

The second solution has the disadvantage of allowing that one tuple member is undefined and the other is not. That's why I like the first variant more, even though it means slightly more code. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.