If a function f: (X => Y) | undefined is possibly undefined, and x: X is defined, then we can use optional-chaining operator ?. to apply f to x:
f?.(x) // ok, no problem if `f` is undefined
But when f: X => Y is defined and x: X | undefined is possibly undefined, there does not seem to be any syntax to "map" the f over the "optional" x:
f(?.x) // not valid syntax; Unclear what to do when `x` is undefined
I could try to implement pipeTo to swap the order of f and x, and then make it work with ?. again, as follows:
function opt<X>(x: X | undefined): { pipeTo<Y>(f: (a: X) => Y): Y } | undefined {
return typeof x === 'undefined' ? undefined : {
pipeTo<Y>(f: (a: X) => Y): Y {
return f(x)
}
}
}
which I could then use as opt(x)?.pipeTo(f), for example:
function square(n: number): number { return n * n }
for (const x of [42, undefined, 58]) {
console.log(opt(x)?.pipeTo(square))
}
Is there any less cumbersome standard solution for applying a certainly existing f to a possibly undefined x?
Clarification: "cumbersome" := anything that forces me to write down the subexpression x twice, or to clutter the scope with meaningless helper-variables.
x is not nullable ? f(x) : ...and inif (... x ... ) { ... x ... } ..., the subexpressionxappears twice, and this is something that I'd really like to avoid. I've added a clarification. I mean, yes, obviously, everything involving?.and??operators could be written down with variables andif-elses, but where's the fun in that?Maybe-like functortype Nullable<T> = T | undefined | null. That operation is usually calledfmap. You could call itfmapNullable(or something less awkward) and implement it like this. Not sure if that's actually better or worse than just doing it manually, though. Does that address the question fully? If so I could write up an answer; if not, what am I missing? (Pls mention @jcalz to notify me if you reply)f?.(x)in there from when I had originally made itapfor applicative functors. Yeah that can be removed. I don't really know what to say about "semi-standard libraries" because my expertise outside of the language itself is limited (but asking about libraries in general is rarely in scope for SO so 🤷♂️). Anyway I'll write up an answer when I get a chance (I have a backlog right now but I hope to get to it today)