Skip to content

refactor(lit): tighten A2uiChildRef type#1520

Merged
andrewkolos merged 3 commits into
a2ui-project:mainfrom
andrewkolos:fix-a2ui-child-ref-type
Jun 4, 2026
Merged

refactor(lit): tighten A2uiChildRef type#1520
andrewkolos merged 3 commits into
a2ui-project:mainfrom
andrewkolos:fix-a2ui-child-ref-type

Conversation

@andrewkolos

@andrewkolos andrewkolos commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

See #1513.

A2uiChildRef is the type that describes a "child to render," used by the helper method renderNode on A2uiLitElement. A2uiLitElement is the base class for Lit A2UI components.

This PR narrows the type from

string | {id?: string; basePath?: string; type?: string}

to the two shapes the protocol actually uses:

ComponentId | {id: ComponentId; basePath: string}

ComponentId is just an alias for string that exists presumably to make the code a little more intuitive to read.

It is technically possible for customer code to get broken (typecheck error) by this change if they took a dependency on specific cases of the previous type definition. Typechecking will fail if a custom component calls this.renderNode with an object literal of the shape {id: 'foo'} (renderNode has fallback behavior to just take the component ID out and pretend it was called as renderNode('foo')). Other object literals (e.g. {basePath: '/path'}) would result in a runtime error, so those cases are not broken by this PR. For whatever's worth, I didn't find any internal override of renderNode or reference to A2uiChildRef that would be broken by this change.

… path

A2uiChildRef declared a third variant (`{type, ...}`) for inline
component definitions, but no schema produces this shape and
`ComponentContext` would reject it at runtime. The matching
`!childRef.type` check in `renderNode` was unreachable.

Tighten the type to `ComponentId | {id: ComponentId; basePath: string}`
and drop the dead branch. Object-variant fields are now required: the
GenericBinder always sets both, and the string variant covers the
bare-id case.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request simplifies the A2uiChildRef type and refactors the renderNode method in a2ui-lit-element.ts to use ComponentId and clean up path resolution. The reviewer suggested making basePath optional in the A2uiChildRef object type to prevent breaking changes for existing code that might omit it, since the runtime logic already handles its absence gracefully.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

* pairing an ID with an explicit data context path.
*/
type A2uiChildRef = string | {id?: string; basePath?: string; type?: string};
type A2uiChildRef = ComponentId | {id: ComponentId; basePath: string};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Making basePath optional in the object type prevents breaking changes for existing customer code that might be passing {id: 'foo'} (as mentioned in the PR description). Since the runtime code in renderNode already gracefully falls back to parentPath when basePath is omitted, making it optional keeps the type tight (preventing runtime errors from missing id or using type) while maintaining backwards compatibility.

Suggested change
type A2uiChildRef = ComponentId | {id: ComponentId; basePath: string};
type A2uiChildRef = ComponentId | {id: ComponentId; basePath?: string};

@andrewkolos andrewkolos Jun 3, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I do not believe the cognitive burden of loose types are worth preserving more lenient typechecking here. I believe very few/no one will be broken by this (see PR description). Even if someone is broken, it will be caught at compilation time and be straightforward to troubleshoot.

@andrewkolos andrewkolos marked this pull request as ready for review June 3, 2026 03:36
@andrewkolos andrewkolos requested a review from josemontespg June 3, 2026 14:44

@josemontespg josemontespg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice, thank you!

@andrewkolos andrewkolos merged commit 6c5aa4b into a2ui-project:main Jun 4, 2026
21 checks passed
@andrewkolos andrewkolos deleted the fix-a2ui-child-ref-type branch June 4, 2026 07:55
@github-project-automation github-project-automation Bot moved this from Todo to Done in A2UI Jun 4, 2026
@andrewkolos andrewkolos linked an issue Jun 4, 2026 that may be closed by this pull request
gspencergoog pushed a commit to gspencergoog/A2UI that referenced this pull request Jun 5, 2026
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.

[web_core] A2uiChildRef type is imprecise

2 participants