为@react-navigation/native的useTheme添加类型定义遇类型错误
问题背景
我已完成styled-components的主题类型配置,但无法为@react-navigation/native的useTheme()设置正确的自定义主题类型。当前尝试后,在使用useTheme()获取的colors对象中访问自定义属性(如activeTab、inactiveTab)时,出现如下类型错误:
Property 'activeTab' does not exist on type '{ primary: string; background: string; card: string; text: string; border: string; notification: string; }'
现有代码
theme.ts
import { DarkTheme, DefaultTheme } from '@react-navigation/native'; export const theme = { light: { ...DefaultTheme, colors: { ...DefaultTheme.colors, primary: '#B0BEC5', secondary: '#29434E', error: '#D32F2F', text: '#212121', border: '#212121', activeTab: '#1976D2', inactiveTab: '#757575', }, }, dark: { ...DarkTheme, colors: { ...DarkTheme.colors, primary: '#212121', secondary: '#29434E', error: '#D32F2F', text: '#FFFFFF', border: '#FFFFFF', activeTab: '#4FC3F7', inactiveTab: '#FFFFFF', }, }, };
类型定义尝试(styled.d.ts)
import '@react-navigation/native'; import theme from './theme'; declare module '@react-navigation/native' { type ThemeType = typeof theme; export interface DefaultTheme extends ThemeType {} }
使用场景(AppNavigator.tsx片段)
import { useTheme } from '@react-navigation/native'; export function AppNavigator() { const { colors } = useTheme(); return ( <Tab.Navigator screenOptions={({ route }) => ({ tabBarActiveTintColor: colors.activeTab, tabBarInactiveTintColor: colors.inactiveTab, // ...其他配置 })} > {/* ...导航页 */} </Tab.Navigator> ); }
错误原因
之前的类型定义错误地将DefaultTheme扩展为包含light和dark两个主题的对象,但useTheme()返回的是当前激活的单个主题实例(而非包含双主题的结构),导致TypeScript无法识别自定义颜色属性。
解决方案
修改类型定义文件(建议命名为navigation.d.ts,放在theme目录下),直接扩展React Navigation主题的colors接口:
方案1:基于现有theme对象提取类型
import '@react-navigation/native'; import { theme } from './theme'; // 提取单个主题的类型(以light/dark主题为例) type LightAppTheme = typeof theme.light; type DarkAppTheme = typeof theme.dark; declare module '@react-navigation/native' { // 让DefaultTheme匹配自定义light主题的类型 export interface DefaultTheme extends LightAppTheme {} // 让DarkTheme匹配自定义dark主题的类型 export interface DarkTheme extends DarkAppTheme {} }
方案2:显式扩展colors接口
如果需要更灵活的定义,可以直接扩展ThemeColors:
import '@react-navigation/native'; declare module '@react-navigation/native' { // 定义自定义颜色属性 export interface ThemeColors { secondary: string; activeTab: string; inactiveTab: string; error: string; } // 让DefaultTheme和DarkTheme的colors继承扩展后的类型 export interface DefaultTheme { colors: ThemeColors; } export interface DarkTheme { colors: ThemeColors; } }
注意事项
- 确保
tsconfig.json的include数组包含类型文件路径,比如:{ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx"] } - 类型文件命名需符合TypeScript的识别规则(后缀为
.d.ts)。
修改完成后,useTheme()返回的colors对象将正确识别自定义属性,类型错误即可解决。
内容的提问来源于stack exchange,提问作者Nilton Schumacher F
相关产品推荐
相关产品推荐

