If I have a `Output<boolean> | undefined` an...
# typescript
w
If I have a
Output<boolean> | undefined
and a function
boolean => string | undefined
I can apply that to get
Output<string | undefined> | undefined
. How can lift the inner
undefined
out so it just becomes ``Output<string> | undefined` ?
l
Would they be undefined in the same circumstances? That is, would it be safe to add
!
to the result of the function call?
Also, is the function under your control? If you can change the return type to just
string
and allow it to throw an exception when it previously returned
undefined
, that would fix it...
| undefined
is a good thing to avoid...
w
I don't think I can add
!
.
undefined
is a legitimate value.
The function is in my control
l
I'd been keen to try to convince you that it's not a legitimate value and to find a slightly different and easier-to-maintain design... it would be easier than your original request...
But you may well be right, in which case, you've got a tough task in front of you. I don't know how to do that, sorry.
w
There is something outside of my control which takes an argument:
foo?: Input<string>
. I have a
boolean
which when
true
I will pass
foo: "bar"
and when
false
then
foo: undefined
. This worked fine until I had to lift the
boolean
into an
Input<boolean>
and now I can't get it to work.
If
Output
had a
filter
method then it would work.
l
Can you eliminate the boolean and pass bar around?
w
It can't be a
string
. It would have to be a
string | undefined
as it is an optional value.
l
But it can be undefined. So
foo: variable ?? undefined
?
Where variable is bar or
undefined
.
Which now that I look at it again, is simply
foo: variable
I guess I'm just guessing and would need more code... 😞
w
I'll write up a more complete example
👍 1
This should be the same as what I am trying to do:
Copy code
interface A {
  something: pulumi.Output<boolean>
}

class B {
  constructor(anotherThing?: Input<string>) {
    // ...
  }
}

function bar(bool?: boolean) {
  new B(bool ? "This is another thing" : undefined)
}

function foo(a?: Input<boolean>) {
  new B(pulumi.output(a).apply(bool => bool ? "This is another thing" : undefined))
}

const a: A = undefined!;

foo(a?.something);
So
bar
works and looks pretty normal (ok maybe it wouldn't be optional but often it is when there is an args type and there is a default). It doesn't seem like much of a jump to go to
foo
.
Hmm actually it isn't going to be possible. The problem is with promises. You can't go from
Promise<boolean>
to
Promise<string> | undefined
Ugh well turns out the types are not entirely correct anyway. It should really be:
Copy code
class B {
  constructor(anotherThing?: Input<string | undefined>) {
    // ...
  }
}
In which case I can use
!
and lie to the compiler.
l
Sorry, got summoned to lunch. I would do my best not have the conditional in the
bar()
function; just pass in the string. And I suppose it's just because it's an MCVE, but
pulumi.interpolate
is suitable for the
foo()
function.
The functional programmers have taught me well. It's all those weeks of advanced Kotlin training, it has blurred the lines between fact and function...
w
It doesn't matter where you move it to, the
boolean
is forever trapped inside the
Output
. In Scala it is the same as trying to do
Future[Boolean] => Option[Future[String]]
which can't be done (at least not in a pure way). I assume Kotlin is the same.
l
Yes, I was thinking more about doing without the boolean, if possible. Conditionally call the code, instead of passing the condition in.
But that's not always possible.