Home > front end >  TypeScript Error 7053 - Creating a custom React component that overrides styles with a prop, how do
TypeScript Error 7053 - Creating a custom React component that overrides styles with a prop, how do

Time:11-05

Here is the code for my custom component. Getting an error that it doesn't like that I gave 'type' the type of string. What is the proper way to define what 'type' is? I'm assuming I would need to define some type of object for it but not sure how to go about doing that.

import React from 'react';
import { StyleSheet, Text, Pressable } from 'react-native';

interface Props {
  text: string;
  type?: string;
  onPress: () => void;
}

const CustomButton: React.FC<Props> = ({ onPress, text, type = 'PRIMARY' }) => {
  return (
    <Pressable
      onPress={onPress}
      style={[styles.container, styles[`container_${type}`]]}
    >
      <Text style={[styles.text, styles[`text_${type}`]]}>{text}</Text>
    </Pressable>
  );
};

export default CustomButton;

const styles = StyleSheet.create({
  container: {
    width: '100%',
    padding: 15,
    marginVertical: 5,
    alignItems: 'center',
    borderRadius: 5,
  },
  container_PRIMARY: {
    backgroundColor: '#3B71F3',
  },
  container_TERTIARY: {},
  text: {
    fontWeight: 'bold',
    color: 'white',
  },
  text_TERTIARY: {
    fontWeight: 'normal',
    color: 'gray',
  },
});

CodePudding user response:

Since you're trying to use a dynamically generated key for the styles object, TS is complaining because the type property is of string type, which could be any string and therefore not match a key from the styles object.

One way to fix this would be to cast the type property to keyof typeof styles:

const CustomButton: React.FC<Props> = ({ onPress, text, type = 'PRIMARY' }) => {
  const containerKey = `container_${type}` as keyof typeof styles;
  const textKey = `text_${type}` as keyof typeof styles;

  return (
    <Pressable onPress={onPress} style={[styles.container, styles[containerKey]]}>
      <Text style={[styles.text, styles[textKey]]}>{text}</Text>
    </Pressable>
  );
};

But since casting is not reliable, you could also set the type of the type property to be of a string literal TS type:

type TERTIARY = 'TERTIARY';

interface Props {
  text: string;
  type?: 'PRIMARY' | TERTIARY;
  onPress: () => void;
}

const CustomButton: React.FC<Props> = ({ onPress, text, type = 'PRIMARY' }) => {
  return (
    <Pressable onPress={onPress} style={[styles.container, styles[`container_${type}`]]}>
      {/* An error would still be displayed here since the styles object doesn't have a text_PRIMARY field  */}
      {/* <Text style={[styles.text, styles[`text_${type}`]]}>{text}</Text> */}

      {/* If there's no other option, you could resort to casting */}
      <Text style={[styles.text, styles[`text_${type as TERTIARY}`]]}>{text}</Text>
    </Pressable>
  );
};
  • Related