1

I am trying to follow a tutorial to learn react in type script. However when I build my solution I get and error. Code

import React, { useState, useEffect } from 'react';
import axios from 'axios';


const DataFetching = () => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts')
      .then(res => {
        console.log(res)
        setPosts(res.data)
      })
      .catch(err => {
        console.log(err)
      })
  })
  return (
    <div>
      <ul>
        {posts.map(post => (<li key={post.id}>{post.title}</li>))}
      </ul>
    </div>
  );
};

export default DataFetching;

the error I am getting

TypeScript error in src/DataFetching.tsx(21,43):
Property 'id' does not exist on type 'never'.  TS2339

I am following the following tutorial https://www.youtube.com/watch?v=bYFYF2GnMy8 . Any help or guidance is appreciated

Krishneil
  • 1,432
  • 1
  • 18
  • 26
  • 2
    Does this answer your question? [Set types on useState React Hook with TypeScript](https://stackoverflow.com/questions/53650468/set-types-on-usestate-react-hook-with-typescript) – Etheryte Sep 04 '20 at 12:01

2 Answers2

1

You should add type to useState explicitly. When you provide empty array typescript infer it's type as never[].

const [posts, setPosts] = useState<Post>([]);

  • Do you know why it infers it's type as `never` if not provided or if empty array is provided? – Andru Apr 14 '21 at 12:27
  • 1
    Empty array is `never[]`, because typescript doesn't have information about items, so it assumes it as always empty array. Alternative is pretty much only `any[]` or `unknown[]`, but it's not safe, so it's disabled in strict typescript. https://github.com/microsoft/TypeScript/pull/8944 – Алексей Мартинкевич Apr 14 '21 at 17:15
1

You should always specify the type of the state variable. In this case, you are using an array of Posts. So you must create a Post interface and use that type in useState.

import React, { useState, useEffect } from 'react';
import axios from 'axios';

interface Post {
  id: number;
  title: string;
}

const DataFetching = () => {
  const [posts, setPosts] = useState<Post[]>([]);

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts')
      .then(res => {
        console.log(res)
        setPosts(res.data)
      })
      .catch(err => {
        console.log(err)
      })
  })
  return (
    <div>
      <ul>
        {posts.map(post => (<li key={post.id}>{post.title}</li>))}
      </ul>
    </div>
  );
};

export default DataFetching;

sidthesloth
  • 1,399
  • 1
  • 11
  • 19