0

I have a function, in this case I'm using XLSX.read this function is defined to take one argument, and a second which may be undef (which is what I want).

Yet, when I try to use this function pointfree in an Rxjs Observable, like this

.pipe(
  .map(XLSX.read)
)

I get an error.

error TS2345: Argument of type '(data: any, opts?: ParsingOptions | undefined) => WorkBook' is not assignable to parameter of type '(value: any, index: number) => WorkBook'.
  Types of parameters 'opts' and 'index' are incompatible.
    Type 'number' is not assignable to type 'ParsingOptions | undefined'.

Instead what TypeScript wants is,

.pipe(
  .map( (x:any) => XLSX.read(x) )
),

This is because Observable.operator.map is defined as

map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R>

Why is that map is (project: (value: T, index: number) and not (project: (value: T, index?: number) with an optional index argument which TypeScript seems to support,

In JavaScript, every parameter is optional, and users may leave them off as they see fit. When they do, their value is undefined. We can get this functionality in TypeScript by adding a ? to the end of parameters we want to be optional.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • Could you make this into a [mcve]? Otherwise I'm not sure where to begin other than to say that `.map()`, whatever it is, probably passes arguments to its callback that you don't expect. – jcalz Feb 26 '19 at 16:54
  • @jcalz that must be [what's happening here](https://rxjs-dev.firebaseapp.com/api/operators/map) Why would map only be defined to take `(value: T, index: number) ` why is the index not optional in that type? – Evan Carroll Feb 26 '19 at 17:08
  • 2
    Index is optional, map accepts a function that takes only one argument, but if the function takes 2 arguments it will receive a number, because that's how map is calling it. In general, there's no way of knowing what will happen inside XLSX.read() when it receives number instead of `ParsingOptions`, so TypeScript protects you from that (using map with parseInt is another in[famous example](https://stackoverflow.com/questions/262427/why-does-parseint-yield-nan-with-arraymap)), and you have to use intermediate function that explicitly ignores the second argument. – artem Feb 26 '19 at 17:19
  • Ahh that makes sense @artem if you want make that an answer that would be great I think I can use R.unary() as a wrapper to fix this too, (if I wanted the point free solution) – Evan Carroll Feb 26 '19 at 17:23

0 Answers0