Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RN FlatList with Typescript and Styled Components

SO community,

I can't figure out the correct type definition for an RN FlatList styled with Styled Components in Typescript

So I have type IProduct like that

interface IProduct {
  id: string;
  name: string;
}

and I define the types for the FlatList like that

<FlatList
  data={products}
  renderItem={({ item }: { item: IProduct }) => (
    <SomeComponent item={item} />
  )}
  keyExtractor={(item: IProduct) => item.id}
/>

everything works fine. Typescript does not complain but as soon as I want to style the FlatList like that

const StyledFlatList = styled.FlatList`
  background-color: 'white';
`;

<StyledFlatList
  data={products}
  renderItem={({ item }: { item: IProduct }) => (
    <SomeComponent item={item} />
  )}
  keyExtractor={(item: IProduct) => item.id}
/>

I get lots of Typescript errors

No overload matches this call.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>): ReactElement<StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error.
    Type '({ item }: { item: IProduct; }) => JSX.Element' is not assignable to type 'ListRenderItem<unknown>'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>): 
ReactElement<StyledComponentPropsWithAs<typeof FlatList, DefaultTheme, {}, never>, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error.
    Type '(item: IProduct) => string' is not assignable to type '(item: unknown, index: number) => string'.ts(2769)

index.d.ts(4218, 5): The expected type comes from property 'keyExtractor' which is declared here on type 'IntrinsicAttributes & Pick<Pick<FlatListProps<unknown> & RefAttributes<FlatList<unknown>>, "ref" | "data" | "style" | "ItemSeparatorComponent" | ... 141 more ... | "key"> & Partial<...>, "ref" | ... 144 more ... | "key"> & { ...; } & { ...; } & { ...; }'

index.d.ts(4218, 5): The expected type comes from property 'keyExtractor' which is declared here on type 'IntrinsicAttributes & Pick<Pick<FlatListProps<unknown> & RefAttributes<FlatList<unknown>>, "ref" | "data" | "style" | "ItemSeparatorComponent" | ... 141 more ... | "key"> & Partial<...>, "ref" | ... 144 more ... | "key"> & { ...; } & { ...; } & { ...; }'

Can someone tell me how to fix that error?

like image 427
Thomas Dittmar Avatar asked Oct 21 '20 08:10

Thomas Dittmar


People also ask

Do styled components work with TypeScript?

We need to install some dependencies because styled-components doesn't come with create-react-app. This installs the styled-components types for TypeScript as a dev dependency. We're also going to use Material Icons, so let's install the material-ui package .

How do I use extraData in FlatList?

By passing extraData={selectedId} to FlatList we make sure FlatList itself will re-render when the state changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is a PureComponent and the prop comparison will not show any changes.

What is difference between FlatList and SectionList in React Native?

SectionList s are like FlatList s, but they can have section headers to separate groups of rows. SectionList s render each item in their input sections using the renderSectionHeader and renderItem prop.

How to implement a list of names using TypeScript + styled components?

Let’s imagine that you need to implement a list of names using TypeScript + Styled Components, like the image below: 2. Dependencies If you haven’t installed styled-components yet, open your terminal inside your typescript React Native project, copy and paste the lines below: 3. Implementing without Styled Components

How do you use a flatlist?

To use the flatlist you need 2 primary parts setup. The flatlist main component, where you hold the data you want to list and the props related to the entire list. And the renderItem function, which basically tells each item, how to look and interact.

How do I add a typescript component to yarn?

yarn add styled-components When it’s done installing, run the following: yarn add -D @types/styled-components This installs the styled-components types for TypeScript as a dev dependency.

How to avoid repetition with typescript components?

To avoid repetition, we need to create TypeScript components and pass some CSS properties as props. This will enable us to reuse the components and modify them as we want without the need to write new lines of code in our styles file. The PageText component will be for all the text on the page.


2 Answers

Looks like adding typeof to another suggested solution solved this in a more straightforward way, even allowing you to exclude types from props:

const StyledFlatList = (styled.FlatList`
  background-color: 'white';
` as unknown) as typeof FlatList;

<StyledFlatList
  data={products}
  renderItem={({ item }) => (
    <SomeComponent item={item} />
  )}
  keyExtractor={(item) => item.id}
/>

like image 112
Sam Schooler Avatar answered Sep 22 '22 14:09

Sam Schooler


This simple solution works for me:

interface IProduct {
  id: string;
  name: string;
}

const StyledFlatList = styled(FlatList as new () => FlatList<IProduct>)`
  background-color: #f7f7f7;
`
like image 24
Edicarlos Lopes Avatar answered Sep 22 '22 14:09

Edicarlos Lopes