Search code examples
typescriptreact-nativereact-native-paper

Is there a way to get typed theme from useTheme() hook in react-native-paper


Right now I'm following the theming react-native-paper guide for custom theming. But when trying to consume the theme via the useTheme hook, it looks like that the response I've got as a theme object is not properly/fully typed and respectively I'm not able to use the object destructuring autocomplete.

export const LightTheme = {
  ...PaperDefaultTheme,
  colors: {
    customColor: 'green',
  },
};

<PaperProvider
  theme={
    colorScheme === "dark"
      ? { ...DarkTheme }
      : { ...LightTheme }
}
>
  <AppProvider>
    {{...}}
  </AppProvider>
</PaperProvider>

Here VSCode displays that the inferred type for the theme object is const theme: Theme but does not recognise the theme properties when trying the access them:

import { useTheme } from "react-native-paper";

const theme = useTheme();
// e.g. theme.colors is not autocompleted

Currently as a solution I'm wrapping the useTheme hook in a custom one that returns the desired Theme type from my typings:

import { useTheme as _useTheme } from "react-native-paper";
import { Theme } from "../theme";

export function useTheme(): Theme {
  const theme = _useTheme();
  return theme;
}

At the time of writing, I'm using version 5.0.0-rc.6 5.0.1


Solution

  • As far as the types files show, useTheme has a generic parameter to support a typed object such as:

    const myTheme = { ... };
    type MyTheme = typeof myTheme;
    const theme = useTheme<MyTheme>()
    

    Of course, for the sake of reusability you could mix this with your provided solution:

    import { useTheme as _useTheme } from "react-native-paper";
    import { Theme } from "../theme";
    
    export function useTheme() {
      const theme = _useTheme<Theme>();
      return theme;
    }