Eui: [EuiListGroup] EuiListGroup doesn't accept listItems that contain a size property

Created on 6 Jan 2021  路  2Comments  路  Source: elastic/eui

When listItems contain the size prop, like the following:

const listItems = [
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's',
    },
  ]

return <EuiListGroup listItems={listItems} />

TypesScript complains:

Types of property 'size' are incompatible.
Type 'string' is not assignable to type '"s" | "m" | "xs" | "l" | undefined'.

The group size prop works just fine though:

<EuiListGroup listItems={listItems} size={'s'} />
bug

Most helpful comment

This is an unfortunate aspect of TypeScript, where your listItems variable is detected as the type:

listItems: {
    label: string;
    href: string;
    iconType: string;
    size: string;
}[]

And size's actual value is no longer known. A couple options to get around this:

  1. define size as const, so TS treats the value as 's' instead of the genric string
const listItems = [
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's' as const,
    },
  ]
  1. Define listItems as EuiListGroupItemProps[], forcing TS to validate at creation.
import { EuiListGroupItemProps } from '@elastic/eui'
const listItems: EuiListGroupItemProps[] = [
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's',
    },
  ]
  1. Pass the array into the component directly, which also forces TS to validate at creation
<EuiListGroup
  listItems={[
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's',
    },
  ]}
  />

All 2 comments

This is an unfortunate aspect of TypeScript, where your listItems variable is detected as the type:

listItems: {
    label: string;
    href: string;
    iconType: string;
    size: string;
}[]

And size's actual value is no longer known. A couple options to get around this:

  1. define size as const, so TS treats the value as 's' instead of the genric string
const listItems = [
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's' as const,
    },
  ]
  1. Define listItems as EuiListGroupItemProps[], forcing TS to validate at creation.
import { EuiListGroupItemProps } from '@elastic/eui'
const listItems: EuiListGroupItemProps[] = [
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's',
    },
  ]
  1. Pass the array into the component directly, which also forces TS to validate at creation
<EuiListGroup
  listItems={[
    {
      label: 'First link',
      href: '#/display/list-group',
      iconType: 'calendar',
      size: 's',
    },
  ]}
  />

awesome, thanks for the detailed explanation @chandlerprall.

Was this page helpful?
0 / 5 - 0 ratings