This code

function myFilter(debts:Map<string, number>) : Map<string, number>{ return new Map([...debts] .map(d => [d[0], Math.round(d[1] * 10) / 10]) // error .filter(d => d[1] != 0) ) }

gives an error because the map() ostensibly can yield [string | number][][].

But this does work:

function myFilter(debts:Map<string, number>) : Map<string, number>{ return new Map([...debts] .map(d => [d[0], Math.round(d[1] * 10) / 10] as [string, number]) .filter(d => d[1] != 0) ) }

I don't understand why this assertion is necessary.

asked Sep 29, 2022 at 16:22

Alexander Presber's user avatar

1

Why?

Because TypeScript does not infer a tuple return type in your callback:

.map(d => [d[0], Math.round(d[1] * 10) / 10])

It is inferred to be a union of all of the possible value types at each element: If you rewrite it using an explicit return statement, you can see the inferred type:

TS Playground

.map(d => { const result = [d[0], Math.round(d[1] * 10) / 10]; //^? const result: (string | number)[] return result; })

Alternate solution:

You can also supply a generic type parameter when using Array.prototype.map<T>() instead of using a type assertion:

TS Playground

.map<[string, number]>(d => [d[0], Math.round(d[1] * 10) / 10])

This will satisfy the compiler and help ensure that the value returned by your callback is assignable to the supplied generic type.

answered Sep 29, 2022 at 16:41

jsejcksn's user avatar

1 Comment

Thanks! I wondered why Typescript couldn’t infer that d[0] has to be a string and d[1] a number from the type of d.

2022-09-29T17:41:42.48Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.