React-Native TypeScript:将变量传入样式表对象时出错
这是我正在使用的风格以及我如何使用它
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',
}),
});
这通常在 JS 中可以正常工作,但在 TS 中我会收到这个错误
类型 '(isPasswordSelected: boolean) => { height: number; marginHorizontal: number; marginVertical: number; padding: number; borderRadius: number; backgroundColor: string; borderWidth: number; borderColor: string; }' 不能分配给类型 'ViewStyle | TextStyle | ImageStyle'.ts(2322)
它似乎认为整个函数都是我的类型声明。
错误只出现在 IDE 中,代码运行正常。可能通过更新我的 tsconfig.json 可以解决
我尝试将类型改为 style typings,但无法消除错误
答案#1
函数不是 StyleSheet 的有效组成部分。有很多方法可以实现这一点。最常见的方法是在您的 StyleSheet 中静态地分配样式,然后在 JSX 中动态组合它们:
const styles = StyleSheet.create({
input: {
// everything except your borderColor style
},
});
const YourScreen = () => {
const isPasswordSelected = true; // replace with however you're getting this in your code
return (
<TextInput
style={[styles.input, {
borderColor: isPasswordSelected ? '#458ae6' : 'transparent',
}]
// ...
你也可以将你的样式做成一个返回 StyleSheet 的函数:
const styles = (isPasswordSelected: boolean) => StyleSheet.create({
input: {
// ... everything except your borderColor style
borderColor: isPasswordSelected ? '#458ae6' : 'transparent',
}),
});
答案#2
StylesSheet 不支持使用函数,但你可以改为使用对象或函数,并将返回值类型设置为以下类型之一:ViewStyle | TextStyle | ImageStyle
例如
const styles = {
square: (size: number): ViewStyle => ({
width: size,
height: size,
})
};
另一种方法是使用 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>"
}
});
但这样的话,你会失去其他属性的类型检查,查看演示:
https://snack.expo.dev/BDj-VZJm5
但正如我之前提到的,你可以使用对象或函数,并用这些类型之一来为返回值类型注解: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
});
而最好的方法是使用老派的方法
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;
