Search code examples
typescriptreact-typescript

TS2339: Property 'users' does not exist on type '{}'


Im switching from JS to TS while learning React. Im facing this problem now.

The initial state for my context is empty and it cannot find the properties.

Here the repo if you prefer https://github.com/lets-c-whats/ts-github-finder/blob/main/src/components/users/UserResults.tsx

context file

const GithubContext = createContext({});

interface GithubContextProps {
  children: React.ReactNode;
}

export const GithubProvider = ({ children }: GithubContextProps) => {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState<boolean>(true);

  const fetchUsers = async () => {
    const response = await fetch(`${GITHUB_URL}/users`, {
      headers: {
        Authorization: `token ${GITHUB_TOKEN}`,
      },
    });

    const data = await response.json();

    setUsers(data);
    setLoading(false);
  };

  return (
    <GithubContext.Provider
      value={{
        users,
        loading,
        fetchUsers
      }}
    >
      {children}
    </GithubContext.Provider>
  );
};

export default GithubContext;

Im wraping the App with the provider and within Home component is the component UserResults

import { GithubProvider } from "./context/github/githubContext";
...
function App() {
  return (
    <GithubProvider>
      ...
      <Route path="/" element={<Home />} />
    </GithubProvider>
  );
}

After that Im requesting the values inside the component using the useContext hook

// DEPENDENCIES
import { useEffect, useContext } from "react";
import GithubContext from "../../context/github/githubContext";



function UserResults() {
  const {users, loading, fetchUsers} = useContext(GithubContext)

  useEffect(() => {
    fetchUsers()
  })

  if (!loading) {
    return (
      <div className="grid grid-cols-1 gap-8 xl:grid-cols-4 lg:grid-cols-3 md:grid-cols-2">
        {users.map((user) => {
          return <UserItem key={user.id} userData={user} />;
        })}
      </div>
    );
  } else {
    return <Spinner />
  }
}
export default UserResults;

after all that the app does not work it throws these errors:

TS2339: Property 'users' does not exist on type '{}'.
     8 |
     9 | function UserResults() {
  > 10 |   const {users, loading, fetchUsers} = useContext(GithubContext)
       |          ^^^^^
    11 |
    12 |   useEffect(() => {
    13 |     fetchUsers()


ERROR in src/components/users/UserResults.tsx:10:17

TS2339: Property 'loading' does not exist on type '{}'.
     8 |
     9 | function UserResults() {
  > 10 |   const {users, loading, fetchUsers} = useContext(GithubContext)
       |                 ^^^^^^^
    11 |
    12 |   useEffect(() => {
    13 |     fetchUsers()


ERROR in src/components/users/UserResults.tsx:10:26

TS2339: Property 'fetchUsers' does not exist on type '{}'.
     8 |
     9 | function UserResults() {
  > 10 |   const {users, loading, fetchUsers} = useContext(GithubContext)
       |                          ^^^^^^^^^^
    11 |
    12 |   useEffect(() => {
    13 |     fetchUsers()


ERROR in src/components/users/UserResults.tsx:19:21

TS7006: Parameter 'user' implicitly has an 'any' type.
    17 |     return (
    18 |       <div className="grid grid-cols-1 gap-8 xl:grid-cols-4 lg:grid-cols-3 md:grid-cols-2">
  > 19 |         {users.map((user) => {
       |                     ^^^^
    20 |           return <UserItem key={user.id} userData={user} />;
    21 |         })}
    22 |       </div>

Solution

  • You are not defining your types for your context. Fix would be like this

    type GithubContextTypes = {
        users: User[];
        loading: boolean;
        fetchUsers: () => void;
    }
    
    const GithubContext = createContext({} as GithubContextTypes);