skip to Main Content

Here is the style I’m using and how I’m using it

style={styles.input(isPasswordSelected)}

const styles = StyleSheet.create({
  input: (isPasswordSelected: boolean) => ({
    height: 40,
    marginHorizontal: 20,
    marginVertical: 7,
    padding: 10,
    borderRadius: 10,
    backgroundColor: '#c9c9c9',
    borderWidth: 1,
    borderColor: isPasswordSelected ? '#458ae6' : 'transparent',
  }),
});

This normally works in JS without issues but in ts I get this error

Type ‘(isPasswordSelected: boolean) => { height: number; marginHorizontal: number; marginVertical: number; padding: number; borderRadius: number; backgroundColor: string; borderWidth: number; borderColor: string; }’ is not assignable to type ‘ViewStyle | TextStyle | ImageStyle’.ts(2322)

it seems to think that the entire function is my type declaration.

The error is just in the IDE, code runs fine. Possibly able to solve with an update to my tsconfig.json

I’ve tried changing the typing to style typings but couldn’t get the error to go away

2

Answers


  1. StylesSheet doesn’t support using fuctions but you can use an Object or a Function instead and type the return value with one of these types ViewStyle | TextStyle | ImageStyle

    E.g

    const styles = {
        square: (size: number): ViewStyle => ({
            width: size,
            height: size,
        })
    };
    

    another way is to bypass this issue using StyleSheet.create < any > :

    const styles = StyleSheet.create<any>({
      input: (isPasswordSelected: boolean): TextStyle => ({
        height: 40,
        marginHorizontal: 20,
        marginVertical: 7,
        padding: 10,
        borderRadius: 10,
        backgroundColor: isPasswordSelected ? 'yellow' : 'green',
        borderWidth: 2,
        borderColor: isPasswordSelected ? 'red' : 'transparent',
      }),
      text: {
        noterror: 40, // typescript not show error because of "<any>"
      }
    });
    

    but this way you lost typing of other properties check demo :

    https://snack.expo.dev/BDj-VZJm5

    but as i mentioned before you can use an Object or a Function instead and type the return value with one of these types ViewStyle | TextStyle | ImageStyle :

    const text : ViewStyle = {
      backgroundColor:"white",
      ///anerror : 'error'
    }
    
    const styles = StyleSheet.create<any>({
      input: (isPasswordSelected: boolean): TextStyle => ({
        height: 40,
        marginHorizontal: 20,
        marginVertical: 7,
        padding: 10,
        borderRadius: 10,
        backgroundColor: isPasswordSelected ? 'yellow' : 'green',
        borderWidth: 2,
        borderColor: isPasswordSelected ? 'red' : 'transparent',
      }),
      text : text
    });
    

    enter image description here

    and the best way is to use the old school method

    import * as React from 'react';
    import {
      View,
      Text,
      StyleSheet,
      TextInput,
      ViewStyle,
      TextStyle,
      ImageStyle,
      StyleSheetProperties,
    } from 'react-native';
    
    const styles = StyleSheet.create<>({
      input: {
        height: 40,
        marginHorizontal: 20,
        marginVertical: 7,
        padding: 10,
        borderRadius: 10,
        backgroundColor: "green",
        borderWidth: 2,
      },
      borderColor458ae6: {
        borderColor: "red"
      },
      borderColorTransparent: {
        borderColor: "transparent"
      },
      container: {
        flex: 1,
        backgroundColor: "#ccc",
        justifyContent: "center",
        alignItems: "center"
      }
    });
    
    const inputIsPasswordSelected = (isPasswordSelected: boolean) => {
      return isPasswordSelected
        ? [styles.input, styles.borderColor458ae6]
        : [styles.input, styles.borderColorTransparent];
    };
    
    function App() {
      const [isPasswordSelected, setIsPasswordSelected] = React.useState(false);
      return (
        <View style={styles.container}>
          <Text>React Native App</Text>
          <TextInput
            secureTextEntry={true}
            style={inputIsPasswordSelected(isPasswordSelected)}
            onFocus={() => {
              setIsPasswordSelected(true);
            }}
            onBlur={() => {
              setIsPasswordSelected(false);
            }}
            value="abc"
          />
        </View>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
  2. Functions aren’t a valid part of a StyleSheet. There are many ways of doing this. The most common way is to assign the styles statically in your StyleSheet and then compose them dynamically in your JSX:

    const styles = StyleSheet.create({
      input: {
        // everything except your borderColor style
      },
    });
    
    const Your Screen = () => {
      const isPasswordSelected = true; // replace with however you're getting this in your code
      return (
        <TextInput
          style={[styles.input, {
            borderColor: isPasswordSelected ? '#458ae6' : 'transparent',
          }]
          // ...
    

    You can also make your styles a function that returns a StyleSheet:

    const styles = (isPasswordSelected: boolean) => StyleSheet.create({
      input: {
        // everything except your borderColor style
        borderColor: isPasswordSelected ? '#458ae6' : 'transparent',
      }),
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search