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>
);
};