Исправьте типы Typescript для Firebase в приложении React - PullRequest
0 голосов
/ 05 июля 2019

Я не понимаю, как правильно добавить типы Typescript для Firebase в приложение React?

Я получаю следующую ошибку:

Аргумент типа '({firebase}: Props) => Элемент' не может быть назначен параметру типа 'ComponentType <{}>'. Тип '({firebase}: Props) => Элемент' нельзя назначить типу 'FunctionComponent <{}>'. Типы параметров «__0» и «реквизит» несовместимы. Свойство 'firebase' отсутствует в типе '{children ?: ReactNode; } 'но требуется в типе' 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/firebase npm , он говорит, что Firebase теперь предоставляет свои собственные типы. Но я просто не уверен, как правильно это настроить.

Большое спасибо.

1 Ответ

0 голосов
/ 07 июля 2019

Оказывается, проблема была в моем 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

Проблема заключалась в том, что я не предоставлял тип для createContext: React.createContext<firebase.app.App>, и мне нужно было передать экземпляр firebaseApp в createContext, сделав его так:

const FirebaseContext = React.createContext<firebase.app.App>(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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...