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

2

24

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;
Wire answered 8/6, 2021 at 12:5 Comment(5)
change your value which you are passing to the provider as value={[products, setProducts]}Ornithology
thanks for your comment @Shyam, a new error when i change it to value = {[products, setProducts ]} Type 'IProductItem[] | undefined' is not assignable to type 'IProductItem[]'. Type 'undefined' is not assignable to type 'IProductItem[]'.Wire
change this React.useState<IProductItem[] | undefined>() to React.useState<IProductItem[]>()Ornithology
@Ornithology i did change it, its still the same error messageWire
@Ornithology i fixed it by doing this ` type IProductContext = [IProductItem[] | undefined, React.Dispatch<React.SetStateAction<IProductItem[] | undefined>>]; `Wire
W
6

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.

Wrens answered 8/3, 2022 at 17:33 Comment(2)
In my case I can't saw any other errors except this one, but finally I found out typo in property aboveCompetence
Same here. But I didn't have to change code. I needed to set strict: true in the tsconfig. Unintuitive to have stricter settings produce fewer errors.Unaneled
V
1

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 :)

Vevina answered 3/4, 2022 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.