Skip to content

Incorrect type definition for ItemSeparatorComponent in VirtualizedList #53531

Description

@karaken12

Description

When using a VirtualizedList component (such as FlatList), setting ItemSeparatorComponent to an Element produces a TypeScript error:

error TS2322: Type 'Element' is not assignable to type 'ComponentType<any> | null | undefined'.

This contradicts the code, which checks if the specified component is an element, and also the React Native docs, which state the value can be a Component or an element:

Can be a React Component (e.g. SomeComponent), or a React element (e.g. <SomeComponent />).

Steps to reproduce

  1. Create a new TypeScript file in a React Native project.
  2. Use a component that uses a virtualised list, e.g. FlatList.
  3. Specify the ItemSeparatorComponent attribute on the list as an element.
  4. Run tsc --noEmit to check the types.

This fails with a TS2322 error.

Below is a minimal reproduction, based on the React Native docs.

// Copied from https://reactnative.dev/docs/flatlist?language=typescript

import React from 'react';
import {View, FlatList, StyleSheet, Text, StatusBar} from 'react-native';
import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context';

const DATA = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    title: 'First Item',
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    title: 'Second Item',
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    title: 'Third Item',
  },
];

type ItemProps = {title: string};

const Item = ({title}: ItemProps) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => (
  <SafeAreaProvider>
    <SafeAreaView style={styles.container}>
      <FlatList
        data={DATA}
        renderItem={({item}) => <Item title={item.title} />}
        keyExtractor={item => item.id}
        /* Should be valid, but gives the following error:
         * Type Element is not assignable to type ComponentType<any> | null | undefined */
        ItemSeparatorComponent={<View style={styles.separator} />}
      />
    </SafeAreaView>
  </SafeAreaProvider>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  separator: {
    height: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

React Native Version

0.81.1

Affected Platforms

Build - MacOS

Output of npx @react-native-community/cli info

info Fetching system and libraries information...
System:
  OS: macOS 15.5
  CPU: (10) arm64 Apple M4
  Memory: 110.97 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.19.4
    path: ~/.nvm/versions/node/v20.19.4/bin/node
  Yarn: Not Found
  npm:
    version: 10.8.2
    path: ~/.nvm/versions/node/v20.19.4/bin/npm
  Watchman:
    version: 2025.06.30.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.5
      - iOS 18.5
      - macOS 15.5
      - tvOS 18.5
      - visionOS 2.5
      - watchOS 11.5
  Android SDK: Not Found
IDEs:
  Android Studio: 2025.1 AI-251.26094.121.2512.13840223
  Xcode:
    version: 16.4/16F6
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.15
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /Users/xlh521/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 20.0.0
    wanted: 20.0.0
  react:
    installed: 19.1.0
    wanted: 19.1.0
  react-native:
    installed: 0.81.1
    wanted: 0.81.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Stacktrace or Logs

Error from production code:

> tsc --noEmit

src/components/AvailabilityScreen/AvailabilityScreen.tsx:112:13 - error TS2322: Type 'Element' is not assignable to type 'ComponentType<any> | null | undefined'.

112             ItemSeparatorComponent={<View style={styles.separator} />}
                ~~~~~~~~~~~~~~~~~~~~~~

  node_modules/react-native/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.d.ts:155:3
    155   ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
          ~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from property 'ItemSeparatorComponent' which is declared here on type 'IntrinsicAttributes & { hasReturnToTopButton?: boolean | undefined; } & FlatListProps<[string, AvailabilityItem]>'

And similar error from reproducer:

npx tsc --noEmit  
App.tsx:42:9 - error TS2769: No overload matches this call.
  Overload 1 of 2, '(props: FlatListProps<{ id: string; title: string; }>): FlatList<{ id: string; title: string; }>', gave the following error.
    Type 'Element' is not assignable to type 'ComponentType<any> | null | undefined'.
  Overload 2 of 2, '(props: FlatListProps<{ id: string; title: string; }>, context: any): FlatList<{ id: string; title: string; }>', gave the following error.
    Type 'Element' is not assignable to type 'ComponentType<any> | null | undefined'.

42         ItemSeparatorComponent={<Text>Separator</Text>}
           ~~~~~~~~~~~~~~~~~~~~~~

  node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.d.ts:155:3
    155   ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
          ~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from property 'ItemSeparatorComponent' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FlatList<{ id: string; title: string; }>> & Readonly<FlatListProps<{ id: string; title: string; }>>'
  node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.d.ts:155:3
    155   ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
          ~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from property 'ItemSeparatorComponent' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FlatList<{ id: string; title: string; }>> & Readonly<FlatListProps<{ id: string; title: string; }>>'


Found 1 error in App.tsx:42

MANDATORY Reproducer

https://github.com/karaken12/react-native-virtualizedlist-itemseparatorcomponent-bug

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions