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?
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 .
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.
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.
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
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.
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.
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.
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}
/>
This simple solution works for me:
interface IProduct {
id: string;
name: string;
}
const StyledFlatList = styled(FlatList as new () => FlatList<IProduct>)`
background-color: #f7f7f7;
`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With