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.
CodePudding user response:
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:
.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:
.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.
CodePudding user response:
I don't understand why this assertion is necessary.
Because [string, number]
is only one of several possible combinations/types that (string | number)[]
may cover.
But it could also contain any of these [number]
or [number, string]
or [string, string, string]
and plenty more which are all not compatible with the Map<string, number>
.