skip to Main Content

I’m trying to create an app in react native, but I keep getting this error:

TS2322: Type  typeof Login  is not assignable to type
ScreenComponentType<ParamListBase, "Login"> | undefined
Type  typeof Login  is not assignable to type  ComponentClass<{}, any> 
Types of parameters  props  and  props  are incompatible.
Property  navigation  is missing in type  {}  but required in type  LoginProps 

so I put this code in via chat gpt to try and debug the code

my app.tsx:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { StatusBar } from 'react-native';
import { Footer } from './src/component/footer';
import { Home } from './src/screen/home';
import { Buy } from './src/screen/buy';
import { Shop } from './src/screen/shop';
import Login from "./src/screen/login"; // Assurez-vous que le chemin d'accès est correct

const Stack = createNativeStackNavigator();

function App(): React.JSX.Element {
    return (
        <NavigationContainer>
            <StatusBar />
            <Stack.Navigator
                screenOptions={{
                    headerShown: false,
                }}
                initialRouteName="Login"
            >
                <Stack.Screen name="Home" options={{ animation: 'none' }} component={Home} />
                <Stack.Screen name="Buy" options={{ animation: 'none' }} component={Buy} />
                <Stack.Screen name="Shop" options={{ animation: 'none' }} component={Shop} />
                <Stack.Screen name="Login" options={{ animation: 'none' }} component={Login} />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

export default App;

my login.tsx:


import React from "react";
import AsyncStorage from '@react-native-async-storage/async-storage';
import {StyleSheet, Text, View, Image, TextInput} from "react-native";
import User from "../assets/compile/SVGSrc/assets/user";
import Password from "../assets/compile/SVGSrc/assets/password";
import PasswordTogge from "../assets/compile/SVGSrc/assets/passwordTogge";
import CustomButton from "../component/libs/customButton";
import {NativeStackNavigationProp} from "@react-navigation/native-stack";
import {RootStackParamList} from "../types";
interface LoginProps {
    navigation: NativeStackNavigationProp<RootStackParamList, "Login">; // Remplacez "any" par le type de navigation réel de votre application
}

interface LoginState {
    secureTextEntry: boolean;
}

export default class Login extends React.Component<LoginProps, LoginState> {
    constructor(props: LoginProps) {
        super(props);
        this.state = {
            secureTextEntry: true
        }
    }

    forgotPassword(){

    }
    async componentDidMount() {
        const test = await AsyncStorage.getItem("user");
        await AsyncStorage.removeItem("user")
        console.log(test)
        if (test) {
            this.props.navigation.navigate("Home")
        }
    }

    render() {
        return (
            <View style={style.container}>
                <View style={style.imageContainer}>
                    <View style={style.border}>
                        <Image source={require("./../assets/png/logo.png")} style={style.logo}/>
                    </View>
                </View>
                <View style={style.form}>
                    <View style={{marginTop: "40%"}}>
                        <View style={style.box}>
                            <User width={35} height={35} style={style.picto}/>
                            <TextInput
                                placeholder={"USERNAME"}
                                textAlign={"center"}

                                placeholderTextColor={"#000000"}
                                style={{
                                    borderBottomColor: "#000000",
                                    borderBottomWidth: 1,
                                    width: "75%",
                                }}/>
                        </View>
                        <View style={style.box1}>
                            <Password width={35} height={35} style={style.picto}/>
                            <TextInput
                                placeholder={"PASSWORD"}
                                textAlign={"center"}
                                secureTextEntry={this.state.secureTextEntry}
                                placeholderTextColor={"#000000"}
                                style={{
                                    borderBottomColor: "#000000",
                                    borderBottomWidth: 1,

                                    width: "75%",
                                    alignItems: "center"
                                }}/>

                            <PasswordTogge width={30} height={30} style={{
                                position: "absolute",
                                right: 0,
                                marginTop: 10
                            }} fill={undefined} stroke={undefined}
                                           onPress={() => this.state.secureTextEntry ? this.setState({secureTextEntry: false}) : this.setState({secureTextEntry: true})}/>
                        </View>

                       <View style={{marginTop: 10}}>
                           <Text onPress={() => {
                               this.forgotPassword();
                           }} style={{
                               color: "#000096",
                               textAlign: "right",
                               marginRight: 40,
                               marginTop: 5
                           }}>
                               forgot password
                           </Text>
                           <Text onPress={() => {
                               this.forgotPassword();
                           }} style={{
                               color: "#000096",
                               textAlign: "left",
                               marginLeft: 40,
                               marginTop: -19
                           }}>
                               register now
                           </Text>
                       </View>
                        <CustomButton style={{marginTop: -20}} content={"Connect"} onClick={() => {console.warn("TEST")}}/>
                    </View>
                </View>
            </View>
        )
    }
}

const style = StyleSheet.create({
    container: {
        backgroundColor: "#1B2631",
        height: "100%",
        alignItems: "center",
    },
    imageContainer: {
        marginTop: "25%",
        alignItems: "center",
    },
    border: {
        zIndex: 1,
        borderWidth: 10,
        borderStyle: "solid",
        borderRadius: 87,
        borderColor: "#17202A",
    },
    logo: {
        height: 110,
        width: 110,
        backgroundColor: "#F2F3F4",
        borderRadius: 87,
    },
    form: {
        marginTop: -50,
        backgroundColor: "#F2F3F4",
        width: "75%",
        height: "55%",
        borderRadius: 20,
    },
    box: {

        flexDirection: "row",
        marginLeft: "auto",
        marginRight: "auto",
    },
    box1: {
        flexDirection: "row",
        marginLeft: "auto",
        marginRight: "auto",
        marginTop: 20
    },
    picto: {
        marginRight: 25,
        position: "absolute",
        marginTop: 7
    },
    connectButton: {
        paddingVertical: 12,
        paddingHorizontal: 32,
        borderRadius: 4,
        backgroundColor: 'black',
        width: 100,
        height: 50
    },
    textButton: {
        fontSize: 16,
        lineHeight: 21,
        fontWeight: 'bold',
        letterSpacing: 0.25,
        color: 'white',
    }
})

types.ts:

export type RootStackParamList = {
    Home: undefined;
    Buy: undefined;
    Shop: undefined;
    Login: undefined;
    // Ajoutez d'autres écrans si nécessaire
};

TypeScript Playground

answer from chat gpt for this code :

Thanks for the clarification. Your types.ts file appears to be correctly defined. With the information you’ve provided, it looks like everything is in order.

If you continue to encounter errors despite the fix I suggested earlier, make sure the file names and file locations match the imports and references in your other files.

Also check that you don’t have any other errors in other parts of your code that could affect the use of Login in your App.tsx. If you still can’t find the source of the error, don’t hesitate to provide additional information, such as the full error message or other parts of your code that might be relevant. This could help to resolve the problem more effectively.

I’ve really tried everything, ask chat gpt: https://chat.openai.com/share/c0eff984-65d4-4adf-ab36-251ca46e868b
but the error code persists (the chat is written in french )

2

Answers


  1. The way that works for me is the following:

    1. Use StackScreenProps instead of NativeStackNavigationProp. And change the LoginProps type accordingly.
    2. Add RootStackParamList to createNativeStackNavigator.

    See the full example in this TypeScript playground.

    Login or Signup to reply.
  2. Problem

    The type for the component prop is defined by the ScreenComponentType type:

    type ScreenComponentType<
      ParamList extends ParamListBase,
      RouteName extends keyof ParamList
    > =
      | React.ComponentType<{
          route: RouteProp<ParamList, RouteName>;
          navigation: any;
        }>
      | React.ComponentType<{}>;
    

    reference

    This type is a union type as denoted by multiple types (a.k.a. members) separated by a vertical bar (|). TypeScript will try to work out which member in the union is the valid type with the information it has available. Your error gives a clue as to which member TypeScript resolved this union to (emphasis mine):

    Property ‘navigation’ is missing in type ‘{}’ but required in type ‘LoginProps’

    This means TypeScript resolved this to the second member in the union:

    React.ComponentType<{}>
    

    It did this for two reasons:

    1. ParamList wasn’t defined (because no type was passed to createNativeStackNavigator‘s ParamList type parameter) which meant it couldn’t pass in ParamList to RouteProp and therefore it couldn’t satisfy the first member of the union.
    2. LoginProps did not define a route prop, which is required in the first member of the union.

    Solution

    You’ll need to:

    1. Pass in RootStackParamList to createNativeStackNavigator‘s ParamList type parameter.

      const Stack = createNativeStackNavigator<RootStackParamList>();
      
    2. And, either:

      • Explicitly annotate the route on LoginProps (demo):
        import { RouteProp } from '@react-navigation/native';
        import { NativeStackNavigationProp } from '@react-navigation/native-stack';
        
        // ...
        
        interface LoginProps {
          navigation: NativeStackNavigationProp<RootStackParamList, "Login">;
          route: RouteProp<RootStackParamList, "Login">;
        }
        
      • Or, use the NativeStackScreenProps helper type from React Navigation (demo):
        import { NativeStackScreenProps } from '@react-navigation/native-stack';
        
        // ...
        
        interface LoginProps extends NativeStackScreenProps<RootStackParamList, "Login"> {}
        

    Further reading

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search