'Property 'aboutData' does not exist on type 'never[]'

What is the best way to print array items? It's return error "Property 'post_title' does not exist on type 'never[]'".

How to use interface to define these variables and use them in code for both aboutData and executive array items.

API resoponse

{
    "aboutData": {
        "post_id": 18,
        "post_title": "Established since 2014",
    },
    "executive": [
        {
            "post_id": 39,
            "post_title": "Quality and excellence in everything we do.",
        },
    ],
}

Here is the component file:

const About: React.FC = () => {

    const history = useHistory();
    const [showLoading, setShowLoading] = useState(true);
    const { authValues, setAuthValues } = React.useContext(userContext);
    const [data, setData] = useState([]);

    React.useEffect(() => {
        getAbout();
    }, []);

    const getAbout = async () => {
        setShowLoading(true);

        return api
            .getabout()
            .then((response) => {
                setData(response.data.data);
                console.log(response.data.data);
            })
            .catch((error) => {
                console.log(error);
            });
    };    

    return (
        <IonPage>

      <IonContent fullscreen>
        <IonCard>
          <IonCardContent>
            <IonList className="dash_grid">
               <IonItem>
              <IonLabel>{data.aboutData.post_title}</IonLabel>
              </IonItem>
            </IonList>
            <IonList color="primary" className="history_box">
              {data.executive.length > 0 ? (
                data.executive.map((exec) => {
                  return (
                    <IonItem>
                        <IonText color="medium">{exec.post_title}</IonText>
                    </IonItem>
                  );
                })
              ) : null}
            </IonList>
          </IonCardContent>
        </IonCard>
      </IonContent>
    </IonPage>
    );
};

export default About;


Solution 1:[1]

You should add optional chaining when using map "?". Add it after data.

  {data?.executive.length > 0 ? (
            data?.executive.map((exec) => {

Solution 2:[2]

You inited your data in the wrong way. That was not an array. Change into this

    const [data, setData] = useState(null);
    ...
    if(!data) return null; // you can handle the loading page here when data is not ready yet

    return (
        ...
    )

Solution 3:[3]

[] in TypeScript is automatically inferred as never[]:

    const [data, setData] = useState([]); // useState<never[]>([]);
    //                               ^^  never[]

So you have to tell TypeScript that it's not (and thankfully useState accepts a generic):

    const [data, setData] = useState<{ post_id: number; post_title: string }>([]); // good

But for readability too, use an interface:

interface PostData { post_id: number; post_title: string }

const [data, setData] = useState<PostData[]>([]);

Solution 4:[4]

If you are expecting an object according of the API response, you need to initialize the useState({}) with an empty object instead of an array

const [data, setData] = useState({});

Then you'll have to check if the object has the properties you are expecting in this line:

 <IonLabel>{data?.aboutData?.post_title}</IonLabel>

you can use optional chaining for this part. And also for this line, take care of the properties

 {data?.executive?.length > 0 ? (

Depends on what your trying to do, I'd recommend you to paint the list conditionally depending on the data content.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alija Faji?
Solution 2 Huan Le
Solution 3 hittingonme
Solution 4 vitomadio