bugmagnet
bugmagnet

Reputation: 7769

Why does this ES6 function have this Typescript error and what can I do about it?

I'm running Typescript inside of VSCode and this line

const Felix_Reverse = ([h, ...r]) => r.length > 0 && Felix_Reverse(r) + h || h;

throws the following error with the r parameter to the embedded call to Felix_Reverse highlighted

Argument of type 'any[]' is not assignable to parameter of type '[any, ...any[]]'. 
    Property '0' is missing in type 'any[]' but required in type '[any, ...any[]]'.

What does this mean and how should I properly annotate the function?

Upvotes: 3

Views: 143

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138307

The underlying problem here is that array destructuring serves two different purposes: One is to pass values like a tuple (e.g. React returns such a tuple from useState), on the other hand it is used to access specific parts of an array like you did. Typescript has to type both purposes correctly, thats why it types the array destructured parameter as a tuple type by default:

  const Felix_Reverse = ([t, ...h]: [any, ...any[]]) => /*...*/;

That's great on the one hand, because it prevents:

  Felix_Reverse([])

as that does not fullfill the tuple type (as that has to have a first entry of type any). Now thats exactly what TS complains about, it says Property '0' is missing in type 'any[]' but required in type '[any, ...any[]]'., or in other words: It cannot guarantee that the recursive call has at least one element (actually it could, because of r.length > 0, but the compiler isn't that clever [yet]).

Now to resolve that, we have to turn the tuple type into an array type. Through that, even empty arrays can be passed, however then t might be undefined:

 const Felix_Reverse = ([h, ...r]: string[] | number[]) => r.length > 0 && Felix_Reverse(r) + h || h;

Upvotes: 2

klugjo
klugjo

Reputation: 20885

You need to specify the argument types and return type:

const Felix_Reverse = ([h, ...r]: number[]): number =>
  r.length > 0 && Felix_Reverse(r) + h || h;

In that situation, h will be of type number and r of type number[]

Upvotes: 3

Related Questions