react-native-elements 主题的声明合并

declaration merging for react-native-elements theme

我在我的 react-native 应用程序中使用了 react-native-elements。

我的应用程序使用 ThemeProvider 包装,以将主题传递给所有组件。

<SafeAreaProvider>
 <ThemeProvider theme={Theme}>
    <Loader visible={loader.loading} text={loader.message} absolute={true} />
    <RootNavigation />
  </ThemeProvider>
</SafeAreaProvider>

在主题文件中,我定义了我想在整个应用程序中使用的值。

const theme = {
  colors: {
    primary: '#6A69E2',
    primaryDark: '#4747c2',
    primaryLight: 'rgba(106, 105, 226, 0.35)',
    gray: {
      dark: '#242424',
      default: '#666',
      medium: '#999',
      light: '#ccc',
      lightest: '#e7e7e7',
    },
  },
  text: {
    size: {
      small: 12,
      default: 16,
      large: 18,
      h1: 26,
      h2: 22,
      h3: 20,
    },
  },
  Text: {
    style: {
      fontSize: 16,
      color: '#242424',
      fontFamily: 'Roboto',
    },
  },
  Button: {
    style: {
      borderRadius: 50,
    },
    disabledStyle: {
      backgroundColor: 'rgba(106, 105, 226, 0.35)',
    },
  },
};

export default theme;

对于提供此功能的 react-native-elements 的原始主题的值。例如,我可以使用

访问颜色
const theme = useTheme()
theme.colors.primary

但是当我想添加一些新属性(如 primaryDark)时,我会遇到 linter 错误。

Object literal may only specify known properties, and 'primaryDark' does not exist in type 'RecursivePartial<Colors>'.ts(2322)

在 react-native-elements 的文档中有关于声明合并的部分,但我不明白如何将其存档 https://reactnativeelements.com/docs/customization/#typescript-definitions-extending-the-default-theme.

有人可以帮我解决这个问题吗?

好吧,声明合并仍然有效。这似乎是 lib 方面的错误。

他们的文档说您可以在 module 'react-native-elements' 中扩充 Color 界面。但是目前(截至2021-04-18,v3.3.2)该接口实际上隐藏在module 'react-native-elements/dist/config/colors'内部,没有直接暴露在顶层,很奇怪。

我建议你向他们的 repo 提交问题。没关系,有人已经 filed the issue

在我的机器上测试,以下解决方案有效。

import React from 'react'
import { useTheme, ThemeProvider } from 'react-native-elements'

declare module 'react-native-elements/dist/config/colors' {
  export interface Colors {
    primaryDark: string
    primaryLight: string
  }
}

const ChildComp = () => {
  const theme = useTheme()
  theme.theme.colors.primaryDark // <-- No more error 
  return <div>foobar</div>
}

回复OP的评论。您可以随心所欲地扩充界面,只要扩充的密钥之前不存在即可。例如将 foobar 键添加到 FullTheme.

declare module 'react-native-elements' {
  export interface FullTheme {
    foobar: string
  }
}