React Native TypeScript样式类型不匹配报错解决方案咨询
React Native + TypeScript 样式类型不匹配问题解决
问题描述
我是TypeScript新手,使用React Native开发时,给View元素添加样式后出现类型不匹配报错,以下是相关代码及错误信息:
样式组件代码
import StyleSheet from 'react-native-media-query'; import { useMediaQuery } from 'react-responsive' const { ids, styles } = StyleSheet.create({ viewStyle: { flex: 1, justifyContent: "center", alignItems: "center", alignSelf: "center", '@media (min-width: 1400px)': { width: "20%" }, '@media (min-width: 1000px)': { width: "30%" }, '@media (max-width: 1000px) and (min-width: 700px)': { width: "60%" }, '@media (max-width: 700px)': { width: "70%" }, '@media (max-width: 700px)': { width: "90%" } }, inputStyle: { padding: "10px" }, emailContainer: { justifyContent: "center", AlignItems: "center", alignSelf: "center", ...Platform.select({ native: { margin: 40, }, web: { maxHeight: "10%", }, }), }, }); export { ids, styles };
使用样式的组件代码
import { Input, Button } from "@rneui/themed"; import { useEffect, useState } from "react"; import { Text, View } from "react-native"; import { ids, styles } from "./styles"; export default function InitialEmailComponent() { const [email, setEmail] = useState<string>(""); const [emailError, setEmailError] = useState<string>(""); const handleEmailSubmit = async () => { debugger; }; return ( <View style={styles.viewStyle} dataSet={{ media: ids.viewStyle }} > <Input inputStyle={styles.inputStyle} id="register-email-input" placeholder={"Enter your email"} onChangeText={(email) => setEmail(email)} errorStyle={{ color: "red" }} errorMessage={emailError} /> <Button id="register-email-submit" title="Submit" onPress={handleEmailSubmit} /> </View> ); }
报错信息
src/components/auth/initialEmailComponent/index.tsx:15:11 - error TS2769: No overload matches this call. Overload 1 of 2, '(props: ViewProps | Readonly<ViewProps>): View', gave the following error. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; } | {} | ({ ...; } & {}) | ({ ...; } & {})' is not assignable to type 'StyleProp<ViewStyle>'. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; }' is not assignable to type 'StyleProp<ViewStyle>'. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; }' is not assignable to type 'ViewStyle'. Types of property 'backfaceVisibility' are incompatible. Type 'TextStyle | ViewStyle | "visible" | "hidden" | ImageStyle | undefined' is not assignable to type '"visible" | "hidden" | undefined'. Type 'TextStyle' is not assignable to type '"visible" | "hidden" | undefined'. Overload 2 of 2, '(props: ViewProps, context: any): View', gave the following error. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; } | {} | ({ ...; } & {}) | ({ ...; } & {})' is not assignable to type 'StyleProp<ViewStyle>'. 15 <View style={styles.viewStyle} ~~~~~ node_modules/react-native/Libraries/Components/View/ViewPropTypes.d.ts:234:3 234 style?: StyleProp<ViewStyle> | undefined; ~~~~~ The expected type comes from property 'style' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<View> & Readonly<ViewProps>' node_modules/react-native/Libraries/Components/View/ViewPropTypes.d.ts:234:3 234 style?: StyleProp<ViewStyle> | undefined; ~~~~~ The expected type comes from property 'style' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<View> & Readonly<ViewProps>' src/components/auth/initialEmailComponent/index.tsx:19:9 - error TS2322: Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; } | {} | ({ ...; } & {}) | ({ ...; } & {})' is not assignable to type 'StyleProp<TextStyle>'. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; }' is not assignable to type 'StyleProp<TextStyle>'. Type '{ position?: "fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined; backfaceVisibility?: TextStyle | ... 4 more ... | undefined; ... 73 more ...; translateY?: TextStyle | ... 3 more ... | undefined; }' is not assignable to type 'TextStyle'. Types of property 'position' are incompatible. Type '"fixed" | TextStyle | ViewStyle | "static" | "relative" | "absolute" | "sticky" | ImageStyle | undefined' is not assignable to type '"fixed" | "static" | "relative" | "absolute" | "sticky" | undefined'. Type 'TextStyle' is not assignable to type '"fixed" | "static" | "relative" | "absolute" | "sticky" | undefined'. 19 inputStyle={styles.inputStyle} ~~~~~~~~~~ node_modules/@rneui/base/dist/Input/Input.d.ts:15:5 15 inputStyle?: StyleProp<TextStyle>; ~~~~~~~~~~ The expected type comes from property 'inputStyle' which is declared here on type 'IntrinsicAttributes & InputProps & { children?: ReactNode; } & RefAttributes<PropsWithChildren<InputProps>>' Found 2 errors in the same file, starting at: src/components/auth/initialEmailComponent/index.tsx:15
问题原因
react-native-media-query库的StyleSheet.create方法返回的样式类型定义过于宽泛,没有和React Native原生的ViewStyle、TextStyle做严格对齐。TypeScript会认为样式中的属性(比如backfaceVisibility、position)可能包含其他样式类型(如TextStyle、ImageStyle),但View组件的style属性只接受ViewStyle类型,Input的inputStyle只接受TextStyle类型,因此出现类型不匹配报错。
另外,样式中emailContainer的AlignItems是笔误,应该改成小写开头的alignItems,否则样式不会生效。
修复方法
方法1:使用类型断言明确样式类型
在使用样式时,给样式加上类型断言,告诉TypeScript该样式的具体类型:
import { ViewStyle, TextStyle } from 'react-native'; // 在View组件中使用 <View style={styles.viewStyle as ViewStyle} dataSet={{ media: ids.viewStyle }} > // 在Input组件中使用 <Input inputStyle={styles.inputStyle as TextStyle} // 其他属性 />
方法2:给StyleSheet.create指定泛型约束
在定义样式时,通过泛型明确每个样式对应的类型,让TypeScript在编译阶段就做类型检查:
import StyleSheet from 'react-native-media-query'; import { ViewStyle, TextStyle } from 'react-native'; const { ids, styles } = StyleSheet.create<{ viewStyle: ViewStyle; inputStyle: TextStyle; emailContainer: ViewStyle; }>({ viewStyle: { // 原样式内容 }, inputStyle: { // 原样式内容 }, emailContainer: { justifyContent: "center", alignItems: "center", // 修正笔误:AlignItems -> alignItems alignSelf: "center", ...Platform.select({ native: { margin: 40, }, web: { maxHeight: "10%", }, }), }, }); export { ids, styles };
额外修正:修复样式笔误
将emailContainer中的AlignItems改为alignItems,保证样式正常生效。
内容的提问来源于stack exchange,提问作者monty_lennie
相关产品推荐
相关产品推荐

