Skip to content

Conversation

@CamSoper
Copy link
Contributor

Summary

This PR addresses issue #15682 by documenting the type requirements and limitations for Component Args classes in multi-language components.

Changes

1. Added comprehensive new section to Components concepts page

Added "Component arguments and type requirements" section to content/docs/iac/concepts/components/_index.md covering:

  • Serialization requirements - Explains why arguments must be serializable for the Pulumi engine and multi-language support
  • Supported types - Documents primitive types, arrays, objects, and language-specific Input wrappers
  • Unsupported types - Lists union types, functions, complex generics, and platform-specific types with concrete examples
  • Constructor requirements by language - Details specific requirements for TypeScript, Python, Go, .NET, and Java based on technical information from @julienp in the issue
  • Best practices - Provides guidance on designing component arguments

2. Enhanced Build a Component guide

Updated content/docs/iac/guides/building-extending/components/build-a-component.md by:

  • Adding cross-references from all 5 language sections (TypeScript, Python, Go, C#, Java)
  • Each reference now includes examples of unsupported types and links to comprehensive documentation

3. Examples included

  • TypeScript example showing unsupported patterns (union types, functions) vs. supported patterns
  • Language-specific constructor signatures with requirements clearly stated

Testing

  • make lint passes with 0 errors
  • make build completes successfully
  • ✅ All pre-commit hooks pass
  • ✅ Markdown formatting verified
  • ✅ Cross-references use proper Hugo syntax

Context

Developers were encountering issues with union types and other complex types in Component Args classes but had no documentation explaining these limitations. This change provides clear guidance on what types are supported and why certain types cannot be used in multi-language components.

Fixes #15682

🤖 Generated with Claude Code

This change addresses issue #15682 by documenting the type requirements
and limitations for Component Args classes in multi-language components.

Changes:
- Added comprehensive new section "Component arguments and type requirements"
  to the Components concepts page covering:
  - Serialization requirements and why they're needed
  - Supported types (primitives, arrays, objects, Input wrappers)
  - Unsupported types (union types, functions, complex generics)
  - Language-specific constructor requirements for TypeScript, Python,
    Go, .NET, and Java based on technical details from @julienp
  - Best practices for designing component arguments

- Enhanced Build a Component guide with cross-references from all
  language sections (TypeScript, Python, Go, C#, Java) that mention
  "serializable" to link to the comprehensive documentation

- Included concrete TypeScript example showing unsupported types
  (union types, functions) vs. supported patterns

This ensures developers understand the constraints when authoring
multi-language components and can avoid common pitfalls with
unsupported types.

Fixes #15682

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@claude
Copy link
Contributor

claude bot commented Oct 20, 2025

Review Summary

This PR adds valuable documentation about Component Args type requirements and limitations. The content is comprehensive and addresses issue #15682 effectively. However, there are several style and consistency issues that need to be addressed before merging.


Issues Found

1. Punctuation consistency in "Unsupported types" list

File: content/docs/iac/concepts/components/_index.md:148-151

The list items are missing ending punctuation. Per standard style, list items that are complete sentences should end with periods.

Current:

- **Union types**: TypeScript union types like `string | number` cannot be serialized
- **Functions/callbacks**: Functions cannot be passed as component arguments
- **Complex generic types**: Deeply nested or complex generic types may not serialize correctly
- **Platform-specific types**: Types that exist only in one language and cannot be translated

Suggested:

- **Union types**: TypeScript union types like `string | number` cannot be serialized.
- **Functions/callbacks**: Functions cannot be passed as component arguments.
- **Complex generic types**: Deeply nested or complex generic types may not serialize correctly.
- **Platform-specific types**: Types that exist only in one language and cannot be translated.

2. Passive voice usage

File: content/docs/iac/concepts/components/_index.md:138

Passive voice should be avoided per review criteria.

Current:

Component arguments must be serializable, meaning they need to be convertible to a format that can be transmitted and reconstructed.

Suggested:

Component arguments must be serializable, meaning you must convert them to a format that the engine can transmit and reconstruct.

3. Avoid words like "simple"

File: content/docs/iac/concepts/components/_index.md:286

Per STYLE-GUIDE.md, avoid words that judge difficulty like "simple."

Current:

1. **Keep types simple**: Stick to primitive types, arrays, and simple objects

Suggested:

1. **Use basic types**: Stick to primitive types, arrays, and basic objects

4. Missing periods in best practices list

File: content/docs/iac/concepts/components/_index.md:284-289

The list items are missing ending punctuation for consistency.

Suggested: Add periods to all list items in the "Best practices" section for consistency with standard list formatting.


5. Supported types list punctuation

File: content/docs/iac/concepts/components/_index.md:143-146

Similar to issue #1, this list is also missing ending punctuation.

Suggested: Add periods to all items in the "Supported types" list for consistency.


Positive Observations

  • ✅ Excellent cross-referencing between the concepts page and build-a-component guide
  • ✅ Good use of language chooser for language-specific examples
  • ✅ Clear examples showing both unsupported (❌) and supported (✅) patterns
  • ✅ Comprehensive coverage of constructor requirements for all supported languages
  • ✅ Links follow proper Hugo syntax
  • ✅ Files end with newlines
  • ✅ Headings use proper sentence case

Recommendation

The content is valuable and well-researched. Please address the style and consistency issues above, then this will be ready to merge. The changes are mostly minor punctuation and word choice adjustments.

Mention @claude if you'd like me to review the changes again or help with any fixes.

@CamSoper
Copy link
Contributor Author

@claude Implement your suggestions, please.

@claude
Copy link
Contributor

claude bot commented Oct 21, 2025

Claude finished @CamSoper's task —— View job


All review suggestions implemented

I've successfully applied all 5 style guide fixes to the documentation:

  • Fix punctuation in "Unsupported types" list
  • Fix passive voice on line 138
  • Replace "simple" with "basic" on line 286
  • Add periods to best practices list items
  • Add periods to "Supported types" list items
  • Commit and push changes

Changes made

All modifications were made to content/docs/iac/concepts/components/_index.md:

  1. Unsupported types list - Added periods to all 4 items for consistency
  2. Serialization description - Changed from passive voice ("they need to be convertible to a format that can be transmitted and reconstructed") to active voice ("you must convert them to a format that the engine can transmit and reconstruct")
  3. Best practices Update in the wake of renamepocalypse #2 - Changed "Keep types simple" to "Use basic types" per style guide
  4. Best practices list - Added periods to all 5 items for consistency
  5. Supported types list - Added periods to all 4 items for consistency

The changes have been committed and pushed to the CamSoper/issue15682 branch.


Job run: https://github.com/pulumi/docs/actions/runs/12407803995
Branch: CamSoper/issue15682

- Add ending punctuation to list items in supported/unsupported types sections
- Replace passive voice with active voice in serialization description
- Replace "simple" with "basic" per style guidelines
- Add periods to all best practices list items for consistency

Co-authored-by: Cam Soper <[email protected]>
@pulumi-bot
Copy link
Collaborator

- **Primitive types**: `string`, `number`/`int`, `boolean`.
- **Arrays/lists**: Arrays of any supported type.
- **Objects/maps**: Objects with properties of supported types.
- **Input wrappers**: Language-specific input types that wrap values:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my (limited) experience, all args to a component should be Input<T>, as are all args to custom resources. If you make and args member a plain string, you cannot use the output of another resource as its value and would instead have to create the resource in an apply, which is not good.

Our blanket recommendations should be:

  1. Wrap every scalar member of an args class in an Input type, e.g. pulumi.Input<string>
  2. (Need to figure out what to say for vector types - I believe they should be e.g. pulumi.Input<string[]>, but I can't find an example - we should ask Providers or Core what they think)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For vectors, it looks like we kinda dodged the issue on awsx.ec2.Vpc (our VPC component). Availability zones are plain types (string[]), for example.

@pulumi-bot
Copy link
Collaborator

@pulumi-bot
Copy link
Collaborator

Copy link
Member

@jkodroff jkodroff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the whole, this is an important improvement. We may need to document where to put component documentation.

1. **Wrap all scalar members in Input types**: Every scalar argument should be wrapped in the language's input type (e.g., `pulumi.Input<string>`). This allows users to pass both plain values and outputs from other resources, avoiding the need to use `apply` for resource composition.
1. **Use basic types**: Stick to primitive types, arrays, and basic objects.
1. **Avoid union types**: If you need multiple possible types, consider using separate properties or creating multiple component variants.
1. **Document required vs. optional**: Clearly document which arguments are required and which have defaults.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where, though?

  • Documentation belongs in whatever your language's comment format is if it's just local code.
  • Documentation belongs in the README for an IDP-published component for sure.
  • I don't know whether doc comments (like TSDoc) in the source args class get translated to the generated args in the SDK for a local package.
  • I don't know whether/how Go Provider SDK translated comments in the code into docs in the schema file.

@julienp Do you know?

@julienp do you know?

Copy link
Contributor

@julienp julienp Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Python and TypeScript comments on the args types, the output properties of the component class, as well as a comment on the component class itself all get translated into descriptions in the schema.

class MyCompArgs(TypedDict):
  """doc for the args type itself"""

  someinput: Input[str]
  """doc for someinput"""

class MyComp(ComponentResource):
  """doc for component itself"""
  
  something: Output[str]
  """doc for output something"""

  def __init__(self, args: MyCompArgs, ...): ...

For Go there's an Annotate thing in https://github.com/pulumi/pulumi-go-provider

For Java and Dotnet we have not implemented anything to detect comments.

During codegen these descriptions get translated back into the language's comment format, so the generated SDKs will have these docs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: if dotnet components become a thing, I feel like attributes would make it super easy to do so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have dotnet (and java) components, for example https://github.com/pulumi/pulumi-dotnet/blob/main/integration_tests/provider_component_host/Component.cs

No support for descriptions at the moment though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you probably meant that if they become popular and we put some more time into it :)

@pulumi-bot
Copy link
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Components: Document limitations of input types in Args

4 participants