TypeScript 错误 7053 - 创建自定义 React 组件,用道具覆盖样式,我如何正确地告诉 TS 类型是什么?
TypeScript Error 7053 - Creating a custom React component that overrides styles with a prop, how do I properly tell TS what the type is?
这是我的自定义组件的代码。得到一个它不喜欢我给 'type' 字符串类型的错误。定义 'type' 的正确方法是什么?我假设我需要为其定义某种类型的对象,但不确定如何去做。
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',
},
});
由于您尝试为 styles
对象使用动态生成的密钥,TS 会报错,因为 type
属性 是 string
类型,这可以是任何字符串,因此与 styles
对象中的键不匹配。
解决此问题的一种方法是将 type
属性 转换为 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>
);
};
但由于转换不可靠,您还可以将 type
属性 的类型设置为 string literal
TS 类型:
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>
);
};
这是我的自定义组件的代码。得到一个它不喜欢我给 'type' 字符串类型的错误。定义 'type' 的正确方法是什么?我假设我需要为其定义某种类型的对象,但不确定如何去做。
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',
},
});
由于您尝试为 styles
对象使用动态生成的密钥,TS 会报错,因为 type
属性 是 string
类型,这可以是任何字符串,因此与 styles
对象中的键不匹配。
解决此问题的一种方法是将 type
属性 转换为 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>
);
};
但由于转换不可靠,您还可以将 type
属性 的类型设置为 string literal
TS 类型:
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>
);
};