Title
g

gifted-island-55702

04/02/2021, 10:18 AM
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:
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:
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

little-cartoon-10569

04/03/2021, 6:09 AM
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
const output = new Promise<Map<string, string>>((resolve, reject) => new Map<string, string>());
And use that output variable anywhere that needs an Input.
g

gifted-island-55702

04/06/2021, 7:24 AM
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

little-cartoon-10569

04/06/2021, 8:44 PM
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).