Skip to content

[web_core] Loose unknown/any types in basic-catalog ChildList rendering #1511

@andrewkolos

Description

@andrewkolos

ResolveA2uiProp<ChildList> resolves to any, so props.children is any in every component implementation whose schema uses ChildListSchema.

See also #1296. any/unknown makes code brittle and more cognitively burdensome to reason about. It can even cause LLMs to get confused, e.g. https://github.com/google/A2UI/pull/1510/changes#r3331738566.

Both renderers cast around it locally:

(Angular isn't affected as it rolls its own data binding, not using GenericBinder and thus ResolveA2uiProp)

Fix

Define ResolvedChildRef and ResolvedChildList matching what the binder actually emits:

export type ResolvedChildRef =
  | ComponentId
  | {id: ComponentId; basePath: string};

Then, we either

  1. fix ResolveA2uiProp, which is the clean fix but could theoretically break customer builds at the typechecking step:
 export type ResolveA2uiProp<T> = [NonNullable<T>] extends [Action]
   ? (() => void) | Extract<T, undefined>
   : [NonNullable<T>] extends [ChildList]
-    ? any | Extract<T, undefined>
+    ? ResolvedChild[] | Extract<T, undefined>
     : Exclude<T, DynamicTypes> extends never
       ? any
       : Exclude<T, DynamicTypes>;

or

  1. just define ResolvedChildRef within the renders so at least the renderer code is more readable.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions