简体   繁体   English

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

[英]Correct Typescript types for Firebase in a React app

I am confused as to how to correctly add Typescript types for Firebase to a React app? 我对如何将Firebase的Typescript类型正确添加到React应用感到困惑?

I am getting the following error: 我收到以下错误:

Argument of type '({ firebase }: Props) => Element' is not assignable to parameter of type 'ComponentType<{}>'. 类型'({{firebase}:Props)=>元素'的参数不能分配给'ComponentType <{}>'类型的参数。 Type '({ firebase }: Props) => Element' is not assignable to type 'FunctionComponent<{}>'. 类型'({{firebase}:Props)=>元素'不可分配给'FunctionComponent <{}>'类型。 Types of parameters '__0' and 'props' are incompatible. 参数'__0'和'props'的类型不兼容。 Property 'firebase' is missing in type '{ children?: ReactNode; 类型'{children ?: ReactNode;类型中缺少属性'firebase'。 }' but required in type 'Props'.ts(2345) }”,但在“ Props”类型中必填。ts(2345)

This is with the following component: 这包含以下组件:

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)

Looking at the @types/firebase npm package , it says Firebase now provides it's own types. 查看@types/firebase npm包 ,它说Firebase现在提供了自己的类型。 But I am just unsure how to set this up properly. 但是我不确定如何正确设置它。

Thanks so much. 非常感谢。

Turns out, the issue was my HOC withFirebase : 原来,问题是我的withFirebase HOC:

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

The issue was I wasn't providing a Type to createContext : React.createContext<firebase.app.App> , and I needed to pass an instance of the firebaseApp to createContext , making it like so: 问题是我没有提供createContext的Type: React.createContext<firebase.app.App> ,我需要将React.createContext<firebase.app.App>的实例传递给createContext ,如下所示:

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

I also needed to add a Type for the Component, making withFirebase : 我还需要为该组件添加一个Type,使withFirebase成为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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM