在 React 应用程序中为 Firebase 正确的 Typescript 类型

Posted

技术标签:

【中文标题】在 React 应用程序中为 Firebase 正确的 Typescript 类型【英文标题】:Correct Typescript types for Firebase in a React app 【发布时间】:2019-11-15 23:37:28 【问题描述】:

我对如何将 Firebase 的 Typescript 类型正确添加到 React 应用程序感到困惑?

我收到以下错误:

“( firebase : Props) => Element”类型的参数不可分配给“ComponentType”类型的参数。 类型 '( firebase : Props) => Element' 不可分配给类型 'FunctionComponent'。 参数 '__0' 和 'props' 的类型不兼容。 ' children?: ReactNode; 类型中缺少属性 'firebase' ' 但在 'Props'.ts(2345) 类型中是必需的

这与以下组件有关:

import React from 'react'
import  withFirebase  from '../Firebase'

interface Props 
  firebase: firebase.app.App


const Admin = ( firebase : Props) => 
  const [isLoading, setIsLoading] = React.useState(false)
  const [users, setUsers] = React.useState<U[]>([])

  React.useEffect(() => 
    console.log(typeof firebase)
    setIsLoading(true)

    const usersRef = firebase.database().ref(`users/`)

    usersRef.on(`value`, (snapshot: any) => 
      const usersObj = snapshot.val()
      const usersLi = Object.keys(usersObj).map(key => (
        ...usersObj[key],
        uid: key,
      ))
      setUsers(usersLi)
    )

    setIsLoading(false)

    return () => usersRef.off()
  , [firebase])

  return (
    <div>
      <h1>Admin</h1>
      isLoading && <p>Fetching data...</p>

      <UserList users=users />
    </div>
  )


interface U 
  uid: string
  username: string
  email: string


interface UL 
  users: U[]


const UserList = ( users : UL) => (
  <ul>
    users.map(user => (
      <li
        key=user.uid
        style=
          borderBottom: '1px solid #f4f4f4',
          paddingBottom: '10px',
          marginBottom: '10px',
        
      >
        <span style= display: 'block' >
          <strong>ID:</strong> user.uid
        </span>
        <span style= display: 'block' >
          <strong>username:</strong> user.username
        </span>
        <span style= display: 'block' >
          <strong>Email:</strong> user.email
        </span>
      </li>
    ))
  </ul>
)

export default withFirebase(Admin)

看看@types/firebasenpm package,它说Firebase 现在提供它自己的类型。但我只是不确定如何正确设置。

非常感谢。

【问题讨论】:

【参考方案1】:

原来,问题出在我的 HOC withFirebase

import React from 'react'

const FirebaseContext = React.createContext()

export const withFirebase = Component => (props: any) => (
  <FirebaseContext.Consumer>
    firebase => <Component ...props firebase=firebase />
  </FirebaseContext.Consumer>
)

export default FirebaseContext

问题是我没有向createContextReact.createContext&lt;firebase.app.App&gt; 提供类型,我需要将firebaseApp 的一个实例传递给createContext,使其如下所示:

const FirebaseContext = React.createContext&lt;firebase.app.App&gt;(firebaseApp)

我还需要为组件添加一个类型,使withFirebase

import React from 'react'
import firebaseApp from './firebase'

const FirebaseContext = React.createContext<firebase.app.App>(firebaseApp)

export const withFirebase = (
  Component: React.ComponentType< firebase: firebase.app.App >,
) => (props: any) => (
  <FirebaseContext.Consumer>
    firebase => <Component ...props firebase=firebase />
  </FirebaseContext.Consumer>
)

export default FirebaseContext

【讨论】:

以上是关于在 React 应用程序中为 Firebase 正确的 Typescript 类型的主要内容,如果未能解决你的问题,请参考以下文章

在 React EXPO 中为 React Redux 包装 <App> 在 <Provider>

在 onBindViewHolder 中为 RecyclerView 设置 Firebase 实时数据库参考中的图像

使用 React Native/Stripe/Firebase 一次性付款

Firebase 登录弹出窗口在 Heroku 上自动关闭

为啥这个 NSString 在 FireBase 查询块中为空?

无法在 Firebase 中为“用户”保留“帖子”参考