-3

In the below code,

function f([first, second]: [number, number]){
    console.log(first);
    console.log(second);
}

var input:number[] = [1,2];
f(input);

number[] type variable(input) is passed to f.

Why compiler errors out? Argument of type 'number[]' is not assignable to parameter of type '[number, number]'. Type 'number[]' is missing the following properties from type '[number, number]': 0, 1ts(2345)

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 2
    What else would `[1, 2]` be, other than `[number, number]`? – Cerbrus Apr 25 '18 at 14:48
  • @Cerbrus Can't it be `number[]`? We did this in C, Java... – overexchange Apr 25 '18 at 14:49
  • @Cerbrus A `number[]` array apparently – Bergi Apr 25 '18 at 14:49
  • The question is "Why does this compile/typecheck?", not "How does this work?", right? – Bergi Apr 25 '18 at 14:51
  • `[number, number]` (array of two members that are numbers) is more specific than `number[]` (array of *x* members that are numbers), that is why TypeScript will throw a compilation error. If you reverse the type declaration and use `var input: [number, number]` and `f([first, second]: number[])` it will work. – Terry Apr 25 '18 at 14:51
  • @Bergi `f(input)` does not compile. `f([1, 2])` compiles. I know, why it compiles. – overexchange Apr 25 '18 at 14:53
  • @overexchange As stated, your code is defining `input` specifically as an array of numbers of any length, while the function only accepts an array of 2 numbers. – Terry Apr 25 '18 at 14:55
  • @Bergi This tuple type in TypeScript with square brackets is confusing me unlike python tuples. I think you answered my question – overexchange Apr 25 '18 at 14:55
  • @Terry function `f` does not accept array(`number[]`) type – overexchange Apr 25 '18 at 14:56
  • @overexchange Of course not, as `[number, number]` is not `number[]`. This is *not* a tuple type! It simply means an array of two elements that are of type `number`. This is akin to passing a variable of type `any` into a function that accepts `string`. – Terry Apr 25 '18 at 14:57
  • @Terry you said: *function only accepts an array of 2 numbers*, which is not the case. it accepts tuple type `[number, number]` – overexchange Apr 25 '18 at 14:59
  • @overexchange No I didn't not say that, you're taking it out of context--reread my entire comment. What I meant is the function only accepts an array of 2 numbers, but you are providing an array of unknown length of numbers. Of course it will reject it. – Terry Apr 25 '18 at 15:00
  • @Bergi Below answer looks wrong to me. How can we avoid votes for confusion? – overexchange Apr 25 '18 at 16:11
  • @overexchange You can [edit] your question to avoid confusion. – Bergi Apr 25 '18 at 17:47
  • @Bergi Edited the question, as you suggested – overexchange Sep 04 '19 at 23:43

2 Answers2

3

TypeScript can be very specific in what it expects to be passed to a method.

For your example:

function f([first, second]: [number, number]){
    console.log(first);
    console.log(second);
}

This will work:

var x: [number, number] = [1,2];

f([1,2]); // Type is implied:  [number, number]
f(x);     // Type is explicit: [number, number]

This won't:

var x = [1,2,3];
var y = [1,2];
var z: number[] = [1,2];

f(x); // Type is implied:  number[]
f(y); // Type is implied:  number[]
f(z); // Type is explicit: number[]

You told typescript to expect an array containing 2 numbers. That's why it won't accept anything but an array containing 2 numbers.

You can change the accepted type like this:

function f([first, second]: number[]){
// Keep destructuring ^,      ^ but change the accepted type.
    console.log(first);  
    console.log(second);
}

Then, any of the previous 6 examples will work, as [number, <number...>] are also number[] arrays.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
0

It's not about arrays but simple type checking. It gives you an error, because type number[] is not same as [number, number].

You can change input type to [number, number] as follows

var input: [number, number] = [1, 2]

or keep the input as is and do following

f(input as [number, number])

Edit

f([1,2]) works just fine because you are explicitly passing two numbers.

Bunyamin Coskuner
  • 8,719
  • 1
  • 28
  • 48