What should be the correct data type for the props.src in TypeScript?

I have a working component that I would like to enhance with proper TypeScript typing for the props. Currently, I am using "any" as the type. Here is my current code snippet:

import React, {useState, useEffect} from "react";

type ImageSrc =  React.SetStateAction<null>

//Here is where I need help with typing the props
const AsyncImage = (props: any) => {
  const [loadedSrc, setLoadedSrc] = useState<ImageSrc>(null);
  useEffect(() => {
      setLoadedSrc(null);
      if (props.src) {
          const handleLoad = () => {
              setLoadedSrc(props.src);
          };
          const image = new Image();
          image.addEventListener('load', handleLoad);
          image.src = props.src;
          return () => {
              image.removeEventListener('load', handleLoad);
          };
      }
  }, [props.src]);
  if (loadedSrc === props.src) {
      return (
          <img {...props} alt=""/>
      );
  }
  return null;
};

export default AsyncImage

Answer №1

When it comes to the src prop, expect a string for the image source. In the case of a different type being used, Typescript allows for specifying the correct type within TProps:

import React, {useState, useEffect, FC} from "react";

type TProps = {
    src: string;
};

//This is where the magic happens
const AsyncImage:FC<TProps> = (props) => {
    const [loadedSrc, setLoadedSrc] = useState<string>("");
    useEffect(() => {
        setLoadedSrc("");
        if (props.src) {
            const handleLoad = () => {
                setLoadedSrc(props.src);
            };
            const image = new Image();
            image.addEventListener('load', handleLoad);
            image.src = props.src;
            return () => {
                image.removeEventListener('load', handleLoad);
            };
        }
    }, [props.src]);
    if (loadedSrc === props.src) {
        return (
            <img {...props} alt=""/>
        );
    }
    return null;
};
export default AsyncImage;

For proper handling of props, React.FunctionComponent (or React.FC) serves as the necessary component type.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Checking for unnecessary properties in Typescript with vue-i18n

Let's consider two different languages represented in JSON format: jp.json { "hello": "こんにちは" } ge.json { "hello": "hallo", "world": "welt" } Now, we are going to com ...

What is the best way to integrate Next.js with Strapi (or the other way around)?

My goal is to develop an application utilizing Next.js for the frontend, fetching data from a Strapi API hosted on the same server. The plan is to have Strapi handle API and admin routes, while Next.js manages all other routes. I intend to use fetch in Nex ...

Determining the Type of a Variable in TypeScript: Interface or Array of Interface?

After extensive searching online, I have yet to find a suitable solution for my problem. Here is a simplified outline of what I am attempting to achieve: interface list { people: Person | Array<Person> } interface officialList { people: Arr ...

The @HostListener in Angular2 does not function correctly within a component that is inherited from another component

My Angular2-based client-side application has a base class: abstract class BaseClass { @HostListener('window:beforeunload') beforeUnloadHandler() { console.log('bla'); } } and two similar derived classes: @Component({ ...

The error message in Angular4 displays code that does not match the intended code to be executed

I am currently developing an application for a website that will handle simplex algorithms. One of my current tasks is to implement a feature that allows the user to input the number of coefficients and constraints, give them custom names, and then have th ...

Tips for incorporating a class as a data type in a variable using TypeScript

I am finding it a bit challenging to understand how to implement OOP in TypeScript after being familiar with PHP. 1 - Is it possible to use a class as a type without needing to populate all the attribute values? 2 - Must I always create an interface to d ...

An unexpected error occurred while running ng lint in an Angular project

I've encountered an issue while trying to run ng lint on my Angular project. After migrating from TSLint to ESLint, I'm getting the following error message when running ng lint: An unhandled exception occurred: Invalid lint configuration. Nothing ...

`Cannot retrieve object`

this.deleteValue = { LanguageId : '', LanguageName : '', LongName : '', CreatedBy : '', UpdatedBy : '', CreatedDate : '', ...

Typescript mistakenly infers the wrong type: TS2339 error - it says that property 'selected' is not found on type 'string'

When examining the code snippet below, Typescript initially infers a type string for the inner element type of the values array. However, it subsequently raises an error indicating that string does not have the property "selected". let item = { values: [{ ...

How to customize the default color palette in Bootstrap 5 for a Next.js project using Sass?

After successfully loading and implementing Bootstrap in my next.js app, I have been struggling for several days to customize the default color scheme. In my global.scss file: @import "../node_modules/bootstrap/scss/bootstrap"; $primary:#f3ced6 ...

Error encountered while building with Next.js using TypeScript: SyntaxError - Unexpected token 'export' in data export

For access to the code, click here => https://codesandbox.io/s/sweet-mcclintock-dhczx?file=/pages/index.js The initial issue arises when attempting to use @iconify-icons/cryptocurrency with next.js and typescript (specifically in typescript). SyntaxErr ...

Angular application experiencing loading issues on Firefox caused by CSP problems

I am encountering an issue while trying to access my app on the testing server. The internal URL I am using is: . However, when I visit the page, it appears completely blank and upon inspecting the dev console, I see the following error message. This situa ...

Module 'serviceAccountKey.json' could not be located

I'm encountering an issue while trying to incorporate Firebase Functions into my project. The problem lies in importing the service account key from my project. Here is a snippet of my code: import * as admin from 'firebase-admin'; var ser ...

Typescript: organizing nested types within an interface

My goal is to create an interface CountersData based on my JSON data. The challenge lies in the nested id property, which contains an array of nested dictionaries. I want this property to be optional. However, I have not been successful in making it option ...

What is the purpose of [el as type] syntax when retrieving a value from a Record?

Can anyone explain to me why I need to use the code return DNAtoRNA[el as DNA] to access the value of a Record? Why do I encounter a linting error when attempting to access it using DNAtoRNA[el]? I had the impression that a Record in TS was similar to a M ...

Idiosyncratic TypeScript behavior: Extending a class with comparable namespace structure

Lately, I've been working on creating a type library for a JavaScript written library. As I was defining all the namespaces, classes, and interfaces, I encountered an error TS2417 with some of the classes. I double-checked for any issues with method o ...

Mapped types: Specify mandatory properties depending on whether an array of identical objects includes a specific string value

Can an object property be set to required or optional based on the presence of a specific string in an array within the same object? type Operator = "A" | "B" type SomeStruct = { operators: Operator[]; someProp: string; // this should be ...

Stage setting timeout for the playwright

const test = defaultTest.extend({ audit: async ({ page }) => { await page.screenshot({ path: 'e2e/test.png' }); console.info('audit done!'); }, }); // ...more code test.only('audit', async ({ page, mount, audi ...

In TypeScript, how does "number" differ from "Number"?

Within the realm of TypeScript, there exist two distinct variations of the "number" type. The first is denoted as lowercase number, whereas the second is represented in uppercase as Number. Attempting to display number results in a compiler error: console. ...

Guide to resolving the error "Type 'void' cannot be assigned to type 'Function' in VueJS"

I've created a Vue component that requires a function pointer to execute a delete action. <template> <q-card class="my-card" > <q-img :src="media.normal || media.original"> <div class="absolute ...