A solution to the error message "Type 'unknown' is not assignable to type 'Country[]' in React TypeScript" is to explicitly define the type of the

I encountered error TS2322: Type 'unknown' is not assignable to type 'Country[]'

https://i.sstatic.net/O4gUu.png

pages/Countries/index.tsx

Full code:

import * as ApiCountries from '../../services/APIs/countries.api'

function Countries() {
  const findCountriesCallback = useCallback(() => ApiCountries.findAll(), [])
  const { execute: fetchCountries, value: countries } = useAsync(findCountriesCallback)

  useEffect(() => {
    ;(async () => await fetchCountries())()
  }, [fetchCountries])

  return (
    <InfiniteScroll
      items={countries}     // I don't understand why `countries` is `unknown` type
      renderEmptyList={() => (
        <div className="text-light-text dark:text-dark-text">
          No Content
        </div>
      )}
      keyExtractor={({ alpha3Code }) => alpha3Code}
      renderItem={renderItem}
      className="flex flex-col mt-8 md:flex-row md:flex-wrap gap-14 justify-between"
    />
  )
}

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

These are three files that I think according.

services/APIs/countries.api.ts

(API from )

const BASE_URL = 'https://restcountries.eu/rest/v2'
export async function findAll() {
  return await fetch(`${BASE_URL}/all`)
}

export async function findByName(name: string) {
  return await fetch(`${BASE_URL}/name/${name}`)
}

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

useAsync.tsx

(this hook implement to handle success and error of async function)
Full code:

function useAsync<T, E>(
  asyncFn: (params?: any) => Promise<Response>,
  immediate: boolean = true
) {
  const [value, setValue] = useState<T | Array<T> | null>(null)
  const [error, setError] = useState<E | Response | null>(null)
  const [pending, setPending] = useState(false)

  const execute = useCallback(async (params?) => {
    setPending(true)
    try {
      const response: Response = await asyncFn(params)
      if (!response.ok) {
        setError(response)
        return
      }

      setValue(await response?.json())
    } catch (err) {
      setError(err)
    }
  }, [asyncFn])

  useEffect(() => {
    if (immediate) {
      ;(async () => await execute())()
    }
  }, [execute, immediate])

  return { execute, value, pending, error }
}

export default useAsync

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

components/InfiniteScroll.tsx

type InfiniteScrollProps<T> = {
  items: Array<T>
  renderItem: (
    itemProps: {
      item: T
      idx: number
      array: Array<T>
      key: string | number
    },
  ) => React.ReactNode
  renderEmptyList?: () => React.ReactNode
  keyExtractor: (item: T, idx: number) => string
  className?: string
}

function InfiniteScroll<T>({
  items,
  keyExtractor,
  renderItem,
  renderEmptyList,
  className
}: InfiniteScrollProps<T>) {
  console.log({items})
  return (
    <div className={`${className ? className: ''} infinite-scroll`}>
      {renderEmptyList && !items?.length && renderEmptyList()}
      {items?.map((item, idx, array) => {
        return renderItem({ item, idx, array, key: keyExtractor(item, idx) })
      })}
    </div>
  )
}

export default InfiniteScroll

Who know how to fix this error ?

================================

Addition question after fixed above error:

I have a new question about type casting for strong type. Now, I refactor code of api function and useAsync hook to be below... but I still have the same error if I don't use an as keyword

<InfiniteScroll
  items={countries as Array<Country>}
/>

services/countries.api.ts

import axios from 'axios'

export async function findAll(params?: {
  searchField?: string
  region?: string
}) {
  if (params?.searchField || params?.region) {
    return await axios.get(`${BASE_URL}/name/${params.searchField}`)
  }
  return await axios.get(`${BASE_URL}/all`)
}

hooks/useAsync.tsx

(I have already casted strong type to be Array<T> | T before return value from this hook)

function useAsync<T, E>(
  asyncFn: (params?: any) => Promise<any>,
  immediate: boolean = true
) {
  const [value, setValue] = useState<T | Array<T> | null>(null)
  const [error, setError] = useState<E | null>(null)
  const [pending, setPending] = useState(false)

  const execute = useCallback(
    async (params?) => {
      setPending(true)
      try {
        // Type casting this line before return value from this hook
        const { data }: { data: Array<T> | T } = await asyncFn(params)
        setValue(data)
      } catch (err) {
        setError(err)
        console.error('❌ Error', err.message)
      }
    },
    [asyncFn]
  )

  useEffect(() => {
    if (immediate) {
      ;(async () => await execute())()
    }
  }, [execute, immediate])

  return { execute, value, pending, error }
}

Answer №1

To successfully assign a variable to your desired type, you must first cast it as 'any' before casting it as the specified type.

const  variable = countries as any as yourtypearray

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

Typescript - Certain implementations may eliminate the optionality of properties

After exploring multiple versions of the Omit implementation, including the one displayed by Intellisense when hovering over Omit, I'm struggling to grasp why certain implementations are homomorphic while others are not. Through my investigation, I&a ...

Express: Every declaration of 'user' must have the same modifiers

In my application, I am utilizing both express and passport. Within these packages, there is a user attribute within the Request interface. Currently, the express package has a user attribute in the request object, such as req.user, but no additional prope ...

Adding a static global constant in webpack dynamically

I'm facing a challenge with adding a global constant to my project using webpack.DefinePlugin. I've successfully added one in the module.exports, but I struggle to do this conditionally. When I declare and use '__VERSION__' in my module ...

Trouble with Displaying Events on React Big Calendar with Typescript

Struggling to implement React Big Calendar with TypeScript. Managed to get the calendar to display correctly after adjusting the height, but unable to show any events. The array of events is populating as expected, and I modified the code for TypeScript co ...

Updating the text area value based on the selected option in a dropdown using Typescript within Angular6

I'm currently facing an issue with updating the text area value based on the selection from a dropdown menu. Below is the design of the dialog: Here's the code snippet I've incorporated for this functionality: <div class="modal-cont ...

AOT compile error due to Angular interpolation syntax

I am facing an issue while compiling my application. The AOT compiler is showing an error related to Angular interpolation in an Angular 2 form: Property 'address' does not exist on type 'FirebaseObjectObservable'. Here's a sn ...

Using res.locals with TypeScript in Next.js and Express

In my express - next.js application, I am transferring some configuration from the server to the client using res.locals. My project is written in typescript and I am utilizing "@types/next": "^8.0.6". The issue at hand: typescript is throwing an error st ...

What is the method for instructing the Typescript compiler to process JSX within .ts files?

My .ts files contain .jsx syntax, and I am looking to instruct tsc on how to compile them the way it compiles .tsx files. Is there a way to adjust the configuration of tsc to achieve this? Additionally, are there steps to configure vscode for proper synt ...

Having difficulties injecting a Service into a TypeScript Controller

I recently started working with TypeScript and I created a controller where I need to inject a service in order to use its methods. However, I am facing an issue where I am unable to access the service functions and encountering an error. Error TypeError ...

You cannot utilize Lesson as a JSX Component in Next JS TypeScript

Below is my updated page.tsx code: import Aspects from '@/components/Aspects'; import FreeForm from '@/components/FreeForm'; import Lesson from '@/components/Lesson'; import React from 'react'; import { Route, Route ...

Having trouble setting up react-i18n with hooks and encountering a TypeError: Cannot read property '0' of undefined?

Encountering an error while setting up the react-i18n with hooks: TypeError: Cannot read property '0' of undefined Here's the content of i18n.js: import i18n from 'i18next'; import { initReactI18next } from 'react-i18next/h ...

Using Typescript to import a module and export a sub function

I am currently using mocha for testing a function, but I have encountered an error while running the test file. The structure of my files is organized as follows: server |-test | |-customer.test.ts |-customer.js Here is the content of the customer.js fi ...

Is there a way to execute a code snippet just once when focusing on a specific field?

<form id="myForm"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname"><br> <label for="mname">Middle name:</label> ...

Using boolean value as default input value in React

When trying to set the default value of a controlled checkbox input from my request, I encountered an error stating "Type 'boolean' is not assignable to type 'string | number | readonly string[] | undefined'". Do you have any suggestion ...

In what way can TS uniquely handle each element of an array as the key of an object?

I am struggling with an object that I need to have keys representing every item in the array, each linked to a value of any. Can anyone provide guidance on how to achieve this? Unfortunately, I couldn't find a solution. Here is an example for refere ...

Webpack and TypeScript are throwing an error stating that `$styles` is not defined

I've encountered an issue with my typescript SharePoint spfx solution. After compiling using webpack, my $styles variable becomes undefined even though I am able to use the class names directly. It seems like there might be a configuration problem at ...

Learn how to set up a class using TypeScript decorators

Is there a way to automatically initialize a class when a specific decorator is present above the class? For example: @apiController export class usersControllers extends lib.baseClasses.apiControllerBase().apiController { @lib.decorators.routesRegist ...

React: Issue with input values not correctly updating across multiple fields when changing state toggles

I am working on a React component that needs to update input values for multiple players independently. However, I am facing an issue where toggling a state causes the first input's value to incorrectly propagate to all other inputs. Additionally, cle ...

How do I access the existing context state when useFormContext() is returning null?

Currently using react-admin: ^4.8.3 and react-hook-form: 7.40.0. The code snippet I am working with is: import { useFormContext } from 'react-hook-form' const MyComponent = () => { const {formState: {isValid}} = useFormContext() // caus ...

Enhancing Angular Material: requiring more user engagement for rendering to occur

Encountering an unusual issue with Angular Material: certain components require an additional event, like a click or mouse movement on the targeted div, to trigger the actual rendering process. For instance, when loading new rows in mat-table, some empty ...