1

I have just switched my Javascript react native project to a Typescript project, but when I changed it, I got a lot of errors on inserting functions in StyleSheet()

Previously i used to do it like this:

const Header = ({ someBoolean }) => (
  <View style={styles.conditionalStyle(someBoolean)}>
    <Text></Text>
  </View>
);

const styles = StyleSheet.create({
  conditionalStyle: (someBoolean) => ({
    marginTop: someBoolean ? 20 : 5
  })
});

But when i switched to typescript, it started throwing these errors:

Type `
(absolute: any) => {
  height: number;
  width: number;
  display: string;
  flexDirection: string;
  borderBottomLeftRadius: number;
  borderBottomRightRadius: number;
  position: string;
  zIndex: number;
}` is not assignable to type `ViewStyle | TextStyle | ImageStyle` ts(2322)
Header.tsx(81, 3):
The expected type comes from property `containerMain` which is declared here on type `
NamedStyles<any> | NamedStyles<{
  container: {
    height: number;
    width: number;
    display: "flex";
    flexDirection: "row";
    borderBottomLeftRadius: number;
    borderBottomRightRadius: number;
  };
  ... 8 more ...;
  screen: (absolute: any) => {
    ...;
  };
}> | NamedStyles<...>`

Here is an example of what my code looks like:

const Header: FC<HeaderProps> = ({ someBoolean }) => (
    <View style={styles.conditionalStyle(someBoolean)}>
      <Text></Text>
    </View>
);

const styles = StyleSheet.create({
    conditionalStyle: (someBoolean) => ({ // ERROR
        marginTop: someBoolean ? 20 : 5
    })
});

Is there an alternative way to pass conditional styles/props?

Dev-Siri
  • 592
  • 5
  • 22
  • 1
    Typescript is complaining because Stylesheet expect ImageStyle, ViewStyle, or TextStyle, but you are giving it a function. Here are some ways to solve it: https://stackoverflow.com/questions/71644471/using-a-function-on-stylesheet-typescript-react-native – alvAro365 Jun 12 '22 at 15:27

2 Answers2

6

To do what you are stating you have to pass parameters to your StyleSheet and define it at the top of your component

So in your component do such...

Add parameters to your StyleSheet definition.

export const styling = (someBoolean:boolean) =>
  StyleSheet.create({
    conditionalStyle:{
        marginTop: someBoolean ? 20 : 5
    }
});

Import the Style Function (If from an external file).

import styling from ...

Define styles in your Component.

const Header:FC<HeaderProps> = ({ someBoolean }) => (

    const styles = styling(someBoolean);

    <View style={styles.conditionalStyle}>
      <Text></Text>
    </View>
);

And this way of sending parameters to the StyleSheet will allow you to programmatically update different style values through useState or Redux

josiah henry
  • 101
  • 2
0

An alternative solution (and much easier in my opinion) is to create the StyleSheet INSIDE your component, so you can use all of the props like you regularly do:

const Header = ({ someBoolean }) => {

  const styles = StyleSheet.create({
    conditionalStyle: { 
      marginTop: someBoolean ? 20 : 5
    }
  })

  return (
    <View style={styles.conditionalStyle}>
      <Text></Text>
    </View>
  );
thegera4
  • 70
  • 8
  • This approach is one of the easiest but this will make working in the component more difficult since a style sheet isn't small, and it is just best to seperate to styles from the component ui and logic. – Dev-Siri Jan 27 '23 at 19:03
  • this is not optimized at all. you will recreate all styles at each rerender, – AlainIb Aug 18 '23 at 08:42