Hi! I have a Typescript newbie question about Pulu...
# typescript
g
Hi! I have a Typescript newbie question about Pulumi outputs and promises. I would expect the following to work but I'm getting a type error:
Copy code
const promise = new Promise<Map<string, string>>((resolve, reject) => new Map<string, string>());
const output: pulumi.Output<Map<string, string>> = pulumi.output(promise);
as it fails with:
Copy code
TS2322: Type 'Output<UnwrappedObject<Map<string, string>>>' is not assignable to type 'Output<Map<string, string>>'.   Type 'Output<UnwrappedObject<Map<string, string>>>' is not assignable to type 'OutputInstance<Map<string, string>>'.     Types of property 'apply' are incompatible.       Type '{ <U>(func: (t: UnwrappedObject<Map<string, string>>) => Promise<U>): Output<U>; <U>(func: (t: UnwrappedObject<Map<string, string>>) => OutputInstance<...>): Output<...>; <U>(func: (t: UnwrappedObject<...>) => U): Output<...>; }' is not assignable to type '{ <U>(func: (t: Map<string, string>) => Promise<U>): Output<U>; <U>(func: (t: Map<string, string>) => OutputInstance<U>): Output<U>; <U>(func: (t: Map<...>) => U): Output<...>; }'.         Types of parameters 'func' and 'func' are incompatible.           Types of parameters 't' and 't' are incompatible.             Type 'UnwrappedObject<Map<string, string>>' is missing the following properties from type 'Map<string, string>': [Symbol.iterator], [Symbol.toStringTag]
Am I missing something? I thought that I can "repackage" whatever I have in the promise object into an output object.
l
I don't think you can do this by casting or wrapping: the type of a
pulumi.output(x as Promise<X>)
is going to be an
Output<Promise<X>
. Rather, everywhere that you might use an Output or Promise actually takes an Input, which is a union type including both the Output and the Promise. So you can just ignore the requirement for an Output, and use the Promise directly.
So you could rewrite your example code as
Copy code
const output = new Promise<Map<string, string>>((resolve, reject) => new Map<string, string>());
And use that output variable anywhere that needs an Input.
g
Thank you @little-cartoon-10569. The issue is I want to expose that value as an output property of my ComponentResource class. My understanding is that I should use pulumi.Output type in such cases.
l
You can use any type. Things that you can pass an Output<x> to (almost) always take an Input<x>, which is a union type defined as
x | Promise<x> | Output<x>
. You can export strings, Promises of lists, Outputs of numbers.. whatever you like.
And "outputs" of ComponentResources are just properties, there is no magic to them. The only "output" variables are those exported from Pulumi projects / stacks. Any public properties of ComponentResources, of any time, can be exported and Pulumi will handle it. (With the gotcha that there is no marshalling / unmarshalling, so if you're exporting non-primitives, you're going to have to marshal / unmarshall them yourself).