Shopify / hydrogen

Hydrogen lets you build faster headless storefronts in less time, on Shopify.
https://hydrogen.shop
MIT License
1.36k stars 262 forks source link

Better custom cart fragment typing #2440

Open juanpprieto opened 1 month ago

juanpprieto commented 1 month ago

Discussed in https://github.com/Shopify/hydrogen/discussions/2416

Originally posted by **theocerutti** August 9, 2024 Hello, When we create a cart with a custom `CART_QUERY_FRAGMENT` it creates an incorrect ts typing. Actually, even with your `DEFAULT_CART_QUERY_FRAGMENT` the typing is not correct. If we have to modify the behavior of the cart it's really annoying since we have to override almost every cart types and that's because of *almost* one big issue. So if we create a cart with custom query: ```ts export const CUSTOM_CART_QUERY_FRAGMENT = `#graphql fragment CustomCartApiQuery on Cart { id checkoutUrl totalQuantity }`; const cartHandler = createCartHandler({ storefront, getCartId: cartGetIdDefault(request.headers), setCartId: cartSetIdDefault(), cartQueryFragment: CUSTOM_CART_QUERY_FRAGMENT, cartMutateFragment: CUSTOM_CART_QUERY_FRAGMENT, }); ``` Then theses types: ```ts type CartReturn = Cart & { errors?: StorefrontApiErrors; }; type CartQueryData = { cart: Cart; userErrors?: CartUserError[] | MetafieldsSetUserError[] | MetafieldDeleteUserError[]; }; ``` should be: ```ts import { CustomCartApiQueryFragment } from 'storefrontgenerated.ts'; type CartReturn = CustomCartApiQueryFragment & { errors?: StorefrontApiErrors; }; type CartQueryData = { cart: CustomCartApiQueryFragment; userErrors?: CartUserError[] | MetafieldsSetUserError[] | MetafieldDeleteUserError[]; }; ``` Indeed we shouldn't have `Cart` as type but the real queried fragment: `CustomCartApiQueryFragment` in this case. ---- also `CartGetProps` should allow to add more custom fields since we could add parameter to cart query fragment: it would be nice to have a dynamic `CartGetProps`: we could "read" the custom query fragment and add variable type dynamically to `CartGetProps`. otherwise just add a `extraQueryVariables` prop: ``` type CartGetProps = { ... extraQueryVariables: any[]; }; ```
frandiox commented 1 month ago

The cart handler came out shortly after we had codegen but its typing was a bit complex and never got proper support. I think it's possible but probably not an easy change in TS.