vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
429 stars 82 forks source link

PiT: Unable to assign endpoint list to typed Grid.items without casting #2215

Open manolo opened 3 years ago

manolo commented 3 years ago

Given this Entity

@Endpoint
@AnonymousAllowed
public class GridproEndpoint {
    public List<Client> clients() {
    ... 

It's impossible assign the endpoint result to the grid.items in the following view

@customElement('gridpro-view')
export class GridproView extends View {
  @query('#grid') private grid!: GridElement<Client>;

  render() {
    return html`
      <vaadin-grid-pro id="grid" theme="no-border column-borders">
        <vaadin-grid-pro-edit-column auto-width path="id"></vaadin-grid-pro-edit-column>
        <vaadin-grid-pro-edit-column auto-width path="client"></vaadin-grid-pro-edit-column>
      </vaadin-grid-pro>
    `;
  }

  async firstUpdated(changedProperties: any) {
    super.firstUpdated(changedProperties);
    this.grid.items = await viewEndpoint.clients();
  }

The error in TS is

Type '(Client | undefined)[] | undefined' is not assignable to type 'Client[] | null | undefined'.
  Type '(Client | undefined)[]' is not assignable to type 'Client[]'.
    Type 'Client | undefined' is not assignable to type 'Client'.
      Type 'undefined' is not assignable to type 'Client'.ts(2322)
tomivirkki commented 2 years ago

The array you're trying to assign to grid.items is of type (Client | undefined)[] but the grid you define as GridElement<Client> expects an array of type Client[]. You should make sure that the array you're trying to assign to items is of right type (in this case, an array that can't contain undefined values).

If you want to accept undefined values in the grid.items array (not recommended), you can change the type of grid as GridElement<Client | undefined>, but ideally Fusion should support annotating an endpoint function so that it would produce a client-side type with defined values only (await viewEndpoint.clients() would return Client[] | undefined instead of (Client | undefined)[] | undefined)