'The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps<IProductContext>'

I was creating an online shopping website and tried to use React Typescript for that project, but when I tried to work with Contexts I couldn't fix this problem when I try to export my state in the Provider value

thanks for helping

ERROR

Type '{ products: IProductItem[] | undefined; setProducts: React.Dispatch<React.SetStateAction<IProductItem[] | undefined>>; }' is not assignable to type 'IProductContext'. Object literal may only specify known properties, and 'products' does not exist in type '[IProductItem[], Dispatch<SetStateAction<IProductItem[]>>]'.ts(2322) index.d.ts(332, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps'

Context Code


import * as React from 'react';
import { useQuery } from "react-query";





type IProductContext = [IProductItem[], React.Dispatch<React.SetStateAction<IProductItem[]>>];

export const ProductContext = React.createContext<IProductContext>([[], () => null]);


const ProductProvider: React.FC<{}> = ({children}: { children?: React.ReactNode }) => {


    //fetching products data from a public API
    const getProducts = async (): Promise<IProductItem[]> => 
    await (await fetch("https://fakestoreapi.com/products")).json();

    //Retrieve the data and status using UseQuery
    const {data, isLoading, error} = useQuery<IProductItem[]>('products', getProducts);

    const [products, setProducts] = React.useState<IProductItem[] | undefined>();


    if(!error){
        setProducts(data)
    }
    

    return (
        <ProductContext.Provider value={{products, setProducts}}>
            {children}
        </ProductContext.Provider>
    );

};

export default ProductProvider;


export function useProducts(){
    const context = React.useContext(ProductContext);

    if(!context) throw new Error('useProducts must be inside a ProductProvider.');

    return context;
}

Types:


interface IProductItem{
    id: number
    title: string
    description: string;
    category: string;
    image: string;
    price: number;
    quantity: number;
}

type ProductType = {
    items: IProductItem[]
    saveItem: (item: ICartItem) => void
    updateItem: (id: number) => void
    removeItem: (id: number) => void
} | undefined;


Solution 1:[1]

In my case the issue was caused by other error which preceded this one. Look into the terminal for other errors preceding this one. By fixing the preceding error, this issue disappeared.

Solution 2:[2]

So already there is few remarks,

  • Your context is expecting an Array of IProductItem[] and React.Dispatch<React.SetStateAction<IProductItem[]>.

in reality from what you do here const [products, setProducts] = React.useState<IProductItem[]>(); you can see that there is no value provided for the initialiser. Which means that products will be undefined

  • Secondly, you are giving an object to the provider while you are expecting an array, which lead to an error as well.

To fix that, here is the solution for you:

import * as React from 'react';
import { useQuery } from "react-query";

interface IProductItem {}

// From the code below you can see that the values can be undefined as well
type IProductContext = [IProductItem[] | undefined, React.Dispatch<React.SetStateAction<IProductItem[] | undefined>>];

export const ProductContext = React.createContext<IProductContext>([[], () => null]);


const ProductProvider: React.FC<{}> = ({children}: { children?: React.ReactNode }) => {


    //fetching products data from a public API
    const getProducts = async (): Promise<IProductItem[]> =>
    await (await fetch("https://fakestoreapi.com/products")).json();

    //Retrieve the data and status using UseQuery
    const {data, error} = useQuery<IProductItem[]>('products', getProducts);

    // As explained in the commend at the top, the value are not initialised, therefore they can be undefined
    const [products, setProducts] = React.useState<IProductItem[] | undefined>();


    if(!error){
        setProducts(data)
    }


    // You was giving an object while you did expect an array
    return (
        <ProductContext.Provider value={[products, setProducts]}>
            {children}
        </ProductContext.Provider>
    );

};

export default ProductProvider;

Hope that answer will help you out, do not hesitate if it is not :)

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 Martin Staufcik
Solution 2 Adrien De Peretti