'React-native & typescript: <ImageBackground> component, property 'children' does not exist on type 'IntrinsAttributes &...'

I am struggling to understand why typescript giving me this error message when I use <ImageBackground> and <Image> component from 'react-native'.

error message:

No overload matches this call. Overload 1 of 2, '(props: ImageBackgroundProps | Readonly): ImageBackground', gave the following error. Type '{ children: Element; style: { flex: number; justifyContent: "flex-end"; }; resizeMode: "cover"; source: any; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly'. Property 'children' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly'. Overload 2 of 2, '(props: ImageBackgroundProps, context: any): ImageBackground', gave the following error. Type '{ children: Element; style: { flex: number; justifyContent: "flex-end"; }; resizeMode: "cover"; source: any; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly'. Property 'children' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly'.

primary source code :

import React from "react";
import {
  ImageBackground,
  StyleSheet,
  View,
} from "react-native";

export default function WelcomeScreen() {
  return (
    <ImageBackground
      style={styles.background}
      resizeMode="cover"
      source={require("../assets/images/background.jpg")}
    >
      <View>
        <View style={styles.logginButton}></View>
        <View style={styles.registerButton}></View>
      </View>
    </ImageBackground>
  );
}

const styles = StyleSheet.create({
  background: {
    flex: 1,
    justifyContent: "flex-end",
  },
  logginButton: {
    width: "100%",
    height: 70,
    backgroundColor: "#fc5c65",
  },
  registerButton: {
    width: "100%",
    height: 70,
    backgroundColor: "#4ecdc4",
  },
});

Because the error message sounds like I cannot pass children element in ImageBackground component, so when I changed ImageBackground component to self-closing element (like <ImageBackground source={image source} /> the error message disappears.

The other solution that I am using currently is to define a custom component referring to expo typescript template. In Themed.tsx, the template defined custom <Text> and <View> component to apply custom theme.

the code currently works :

import React from "react";
import {
  ImageBackground as DefaultImageBackground,
  StyleSheet,
  View,
} from "react-native";

type ImageBackgroundProps = DefaultImageBackground["props"] & {
  children: React.ReactNode;
};

function MyBackground(props: ImageBackgroundProps) {
  return <DefaultImageBackground {...props} />;
}

export default function WelcomeScreen() {
  return (
    <MyBackground
      style={styles.background}
      resizeMode="cover"
      source={require("../assets/images/background.jpg")}
    >
      <View>
        <View style={styles.logginButton}></View>
        <View style={styles.registerButton}></View>
      </View>
    </MyBackground>
  );
}

const styles = StyleSheet.create({
  background: {
    flex: 1,
    justifyContent: "flex-end",
  },
  logginButton: {
    width: "100%",
    height: 70,
    backgroundColor: "#fc5c65",
  },
  registerButton: {
    width: "100%",
    height: 70,
    backgroundColor: "#4ecdc4",
  },
});

But I think my solution does not make sense, ImageBackground component should be able to take children element. Is there any syntax error in my primary source code?



Solution 1:[1]

I am also having this issue. I fixed it by changing the version of node I was using. This issue is present on node 16.14.0 through to 16.15.0. I noticed that:

  • node 16.14.2 brings in npm 8.5.0
  • node 16.15.0 brings in npm 8.5.5
  • node 16.3.2 brings in npm 8.1.2
  • node 17.0.0 brings in npm 8.1.0

We just kept the project at 16.13.2 instead of updating.

My current theory is that these differences in npm are causing differences in how tsc interprets rules. I would love to know if I am wrong on that.

Looking in the source code for ImageBackground I see

class ImageBackground extends React.Component<$FlowFixMeProps> {
  setNativeProps(props: Object) {
    // Work-around flow
    const viewRef = this._viewRef;
    if (viewRef) {
      viewRef.setNativeProps(props);
    }
  }

where <$FlowFixMeProps> is set to:

type $FlowFixMeProps = /*unresolved*/ any

Is it possible that tsc is not liking any?

Solution 2:[2]

i had the same issue with ImageBackgroun. The problem lies in TypeScript not detecting children props in ImageBackground interface even though it extended it from another interface. i fix it by adding

    children:React.ReactNode;

in line 3909 of \node_modules@types\react-native\index.d.ts

export interface ImageBackgroundProps extends ImagePropsBase {
imageStyle?: StyleProp<ImageStyle> | undefined;
style?: StyleProp<ViewStyle> | undefined;
imageRef?(image: Image): void;
children:React.ReactNode; //add this line
}

now everything work fin, i hop this fix your problem.

Solution 3:[3]

What version of react-native are you using, if you are using 0.67.x please update @types/react-native to 0.67.6, since that error was fixed.

In case you need to follow @brahim-mahioussi answer you can use PATCH PACKAGE so you don't loose your changes in the node_modules path, but be sure to add the property as optional:

children?: React.ReactNode; //add this line

Solution 4:[4]

Use closed tag. Because inside the ImageBackground type there are no children:

<ImageBackground source={require("./src/exemple.png")} resizeMode="cover" />

But you'll need to use this style:

position: 'absolute',
width: "100%",
height: "100%",

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adam
Solution 2 Brahim Mahioussi
Solution 3 Pablo Gambetta
Solution 4 Josué Mendonça