React Native Paper自定义DefaultTheme时NotoSans字体配置类型错误求助
React Native Paper PaperProvider 主题字体配置类型错误解决
问题原因
你遇到的类型错误源于React Native Paper V3版本的主题结构变更:
- V2主题(
DefaultTheme)使用fonts属性定义字体配置,类型为Fonts - V3主题(
MD3LightTheme/MD3DarkTheme)使用typescale属性替代,类型为MD3Typescale - 当前
PaperProvider期望接收V3主题的$DeepPartial<MD3Theme>类型,而你基于V2的DefaultTheme扩展并使用fonts属性,导致类型不兼容。
解决方案
迁移到V3主题规范,调整主题基础和字体配置属性:
- 将主题基础从
DefaultTheme替换为V3的MD3LightTheme或MD3DarkTheme - 将字体配置的属性名从
fonts改为typescale - 确保
configureFonts的isV3参数设为true
修改后的代码示例
import 'react-native-gesture-handler'; import React from 'react'; import {RecoilRoot} from 'recoil'; import MainNavigation from './src/navigation/MainNavigation'; import {ToastProvider} from 'react-native-toast-notifications'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {en, registerTranslation} from 'react-native-paper-dates'; import {configureFonts, MD3LightTheme, PaperProvider} from 'react-native-paper'; import {Platform, StyleSheet} from 'react-native'; import {AxiosProvider} from './src/common/context/AxiosContext'; import './lang/i18n.config'; // internationalization const fontConfig = { web: { regular: { fontFamily: 'NotoSans-Regular', fontWeight: 'normal', }, medium: { fontFamily: 'NotoSans-Medium', fontWeight: 'normal', }, light: { fontFamily: 'NotoSans-Light', fontWeight: 'normal', }, thin: { fontFamily: 'NotoSans-Thin', fontWeight: 'normal', }, }, ios: { regular: { fontFamily: 'NotoSans-Regular', fontWeight: 'normal', }, medium: { fontFamily: 'NotoSans-Medium', fontWeight: 'normal', }, light: { fontFamily: 'NotoSans-Light', fontWeight: 'normal', }, thin: { fontFamily: 'NotoSans-Thin', fontWeight: 'normal', }, }, android: { regular: { fontFamily: 'NotoSans-Regular', fontWeight: 'normal', }, medium: { fontFamily: 'NotoSans-Medium', fontWeight: 'normal', }, light: { fontFamily: 'NotoSans-Light', fontWeight: 'normal', }, thin: { fontFamily: 'NotoSans-Thin', fontWeight: 'normal', }, } } as const; const theme = { ...MD3LightTheme, colors: { primary: "rgb(207, 65, 36)", onPrimary: "rgb(255, 255, 255)", primaryContainer: "rgb(219,255,224)", onPrimaryContainer: "rgb(44, 0, 81)", secondary: "rgb(102, 90, 111)", onSecondary: "rgb(255, 255, 255)", secondaryContainer: "rgb(219,255,224)", onSecondaryContainer: "rgb(33, 24, 42)", tertiary: "rgb(128, 81, 88)", onTertiary: "rgb(255, 255, 255)", tertiaryContainer: "rgb(219,255,224)", onTertiaryContainer: "rgb(50, 16, 23)", error: "rgb(186, 26, 26)", onError: "rgb(255, 255, 255)", errorContainer: "rgb(255, 218, 214)", onErrorContainer: "rgb(65, 0, 2)", background: "rgb(208,224,232)", onBackground: "rgb(29, 27, 30)", surface: "rgb(154,186,186)", onSurface: "rgb(29, 27, 30)", surfaceVariant: "rgba(91,126,136,0.29)", onSurfaceVariant: "rgb(74, 69, 78)", outline: "rgb(124, 117, 126)", outlineVariant: "rgb(154,186,186)", shadow: "rgb(0, 0, 0)", scrim: "rgb(0, 0, 0)", inverseSurface: "rgb(50, 47, 51)", inverseOnSurface: "rgb(219,255,224)", inversePrimary: "rgb(220, 184, 255)", elevation: { level0: "transparent", level1: "rgba(208,224,232,0.75)", level2: "rgba(208,224,232,0.75)", level3: "rgba(208,224,232,0.75)", level4: "rgba(208,224,232,0.75)", level5: "rgba(208,224,232,0.75)", }, surfaceDisabled: "rgba(29, 27, 30, 0.12)", onSurfaceDisabled: "rgba(29, 27, 30, 0.38)", backdrop: "rgba(51, 47, 55, 0.4)" }, typescale: configureFonts({ config: fontConfig, isV3: true, }), }; const App = () => { console.log('Environment ' + process.env.EXPO_PUBLIC_ENVIRONMENT); console.log('Server URL ' + process.env.EXPO_PUBLIC_SERVER_URL); console.log('S3 URL: ' + process.env.EXPO_PUBLIC_S3_URL); console.log('WEB URL: ' + process.env.EXPO_PUBLIC_WEB_URL); if (Platform.OS !== 'web') { // Honeybadger.configure({ // apiKey: 'hbp_mA9akEG4Bz4BHwGzIWNQ5risUD2nws0OeS86', // }); } registerTranslation('en', en); return ( <GestureHandlerRootView style={styles.container}> <ToastProvider placement="top"> <RecoilRoot> <AxiosProvider> <PaperProvider theme={theme}> <MainNavigation /> </PaperProvider> </AxiosProvider> </RecoilRoot> </ToastProvider> </GestureHandlerRootView> ); }; export default App; const styles = StyleSheet.create({ container: { flex: 1, }, });
额外说明
如果需要保留V2主题结构,可显式指定主题类型为V2的Theme,但React Native Paper官方已逐步废弃V2相关支持,建议优先迁移到V3规范。
内容的提问来源于stack exchange,提问作者David L. Whitehurst
相关产品推荐
相关产品推荐

