7

I am trying to destructure an array of length 2, but I get a typescript error:

[ts] Tuple type '[string]' with length '1' cannot be assigned
to tuple with length '2'.

    let output = {status: false};
    if(execute.permission) {
        let message: [string] = execute.params;
        if(message.length >= 2) {
            // Destructuring follows
            [output['position'], output['message']] = message;
        }
    }

How do I tell typescript, that the array could possiblly be of length 2?

Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328

3 Answers3

11

You've not declared message as an array; you've declared it as a tuple ([string]) and tuples have a fixed number of elements. (See the Tuple section in the Basic Types documentation.)

You could declare it as a tuple that has two string elements ([string, string]), but given that you are testing message.length >= 2 it seems likely you intended to declare it as a string array (string[]):

let output = {status: false};
if(execute.permission) {
    let message: string[] = execute.params;
    if(message.length >= 2) {
        // Destructuring follows
        [output['position'], output['message']] = message;
    }
}
cartant
  • 57,105
  • 17
  • 163
  • 197
6

Use string[] (an array of any length) instead of [string] (a "tuple" limited to length 1) as your type.

Tuples have a specific length and make it easier to represent multiple types assigned to specific index positions, like [string, number]. Homogenous (single-type) tuples are still useful in some scenarios (such as representing pairs in a map), but are not as common.

Arrays, on the other hand, are lists of variable length but are designed to hold only references of a single type (even if that type is a union type or any). If one index of any array can hold a certain value, every index can hold that same kind of value.


TypeScript Code (Playground Link)

let execute = { permission: true, params: ['a', 'b']}


let output = { status: false };
    if(execute.permission) {
        let message: string[] = execute.params;
        if(message.length >= 2) {
            // Destructuring follows
            [output['position'], output['message']] = message;
        }
}

console.log(output)
gyre
  • 16,369
  • 3
  • 37
  • 47
  • I won't downvote but this is a bit off. Arrays of a union type are not uncommon (technically that is still just one type but they result from compiler inference as a heterogeneous array is built up imperatively). Also tuples containing only elements of a single type are also fairly common, for example if you get the entries of `Map`, but I would say that creating homogeneous tuples is a practice best avoided. – Aluan Haddad Mar 31 '17 at 02:00
  • 1
    A union type to me is still a type, but I do think you make a fair point about using tuples to represent homogenous pairs. I will update my answer, and I appreciate you taking the time to give me suggestions rather than downvoting and leaving without a word as so many other users often do. – gyre Mar 31 '17 at 02:05
  • I gave it some thought and your conception of an Array's type is very correct. I was conflating the use of the array as a heterogeneous container with its interface which is defined by a single type argument, whatever that may be, as you say. – Aluan Haddad Mar 31 '17 at 02:34
0

Try to change type of message variable. Array of strings suits better than array with single string

let message: string[] = execute.params;
Zibx
  • 94
  • 4