Skip to content

Shared signals cannot express parameterized value types (no TypeReference) #147

Description

@totally-not-ai

Part of #138. Found while writing the Collaboration Kit to Signals migration guide (vaadin/docs#5888).

Real use case

A user administration form with a CheckboxGroup<String> of roles, or the MultiSelectComboBox from #137. The bound property is a Set<String>, and today it is bound with:

binder.forField(rolesField, Set.class, String.class).bind("roles");

The two class arguments exist precisely because the element type cannot be inferred. On migration to a shared signal there is nowhere to put the second one:

// No way to say "a set of strings"
new SharedValueSignal<>(Set.class);

The value round-trips through JSON as a bare array and comes back without its element type. Multi-select fields are common enough in business forms that most non-trivial CollaborationBinder forms hit this, and the failure is a runtime type problem rather than a compile error, so it surfaces during testing at best.

What Collaboration Kit does

Two ways to name a parameterized type:

  • The topic API takes a Jackson TypeReference wherever it takes a Class, so CollaborationMap.get(key, TypeReference) and CollaborationList.getItems(TypeReference) read a Set<String>.
  • CollaborationBinder.forField(field, Set.class, String.class) takes the collection type and the element type separately.

What signals have

Only Class. Every shared signal constructor takes Class<T>, and reading converts through treeToValue(node, Class). There is no TypeReference overload anywhere in the API.

Suggested direction

Either:

  • TypeReference overloads on the shared signal constructors, matching what the topic API already accepts.
  • Or a two-class form mirroring forField(field, collectionType, elementType).

The guide's workaround is to wrap the collection in a record, which is typed all the way down and serializes as an object. That works, but it forces a data model change on migration for what is a limitation of the type token rather than of the data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions