Typescript intellisense
AaronLayton opened this issue · comments
Hiya folks!
Tried to use this in a project and if I try and add a product using addItem
and then try to map over the items afterwards, Typescript doesn't seem to understand any of the other props that I passed in with my object. It is only doing intellisense on the Item
interface Item {
id: string;
price: number;
quantity?: number;
itemTotal?: number;
[key: string]: any;
}
Seems to fully ignore [key: string]: any;
Is this expected behaviour?
We may need to allow you to pass a generic type that is merged with the item type. Happy to accept any PRs to fix this 😅
I have been experimenting with building a library similar to this for internal use, but perhaps there is a better way.
I had to create a createCartContext
factory function so I could pass in a type
// npm package
type Item<T extends {}> = T & {
id: string;
price: number;
quantity?: number;
itemTotal?: number;
}
interface CartProviderState<T> extends InitialState<T> {
/* ... */
}
export function createCartContext<T>() {
const context = createContext<CartProviderState<T>>(null);
const Provider = ({ children, ...options }: CartProvider<T>) => {
const cartState = getCartState<T>(options);
return (
<context.Provider value={cartState }>{children}</context.Provider>
)
}
return {
context .
CartProvider,
useCart: () => useContext(context)
}
}
Then after importing into my codebase I had to create the new Context
// /context/CartContext.ts
import { createCartContext } from './super-duper-cart`
const cartContext = createCartContext<BasketProduct>();
export const CartProvider = cartContext.CartProvider;
export const useCart = cartContext.useCart;
Nice!
I realise after this that with TypeScript you can have generic components, so could be worth making a Provider that accepts a generic
type MyBasketProduct {
legLength: number
}
<CartProvider<MyBasketProduct> id="basket" onItemAdd={(item) => console.log(item)}>
<MainApp />
</CartProvider>
To add onto this, I would like this to be updated as well:
interface CartProviderState extends InitialState {
addItem: (item: Item, quantity?: number) => void;
removeItem: (id: Item["id"]) => void;
updateItem: (id: Item["id"], payload: object) => void;
updateItemQuantity: (id: Item["id"], quantity: number) => void;
emptyCart: () => void;
getItem: (id: Item["id"]) => any | undefined;
inCart: (id: Item["id"]) => boolean;
}
There is no setItems: (items: Item[]) => void;
in here. I've added PR for this fix, let me know if its good to go because its my first ever code fix on open source.
Thanks for the PR @Skidragon 🚀
@AaronLayton this sounds really awesome - if you're up for it, feel free to PR, and I'll get it merged in 😄
Hi @AaronLayton are you working on this issue? It would be great if this is implemented.