Register a hook in hooks.json and its implementation is typed for you. The language server knows the signatures of 86 system hooks, so in a basket hook basket is a dw.order.Basket and a wrong return value is an error. Your file stays plain JavaScript
What you get
| In the hook function | Result |
|---|---|
| Hover a parameter | Its SFCC type, for example basket: Basket |
Type basket. | Every Basket member with its API docs |
| Return the wrong value | An error such as Type 'boolean' is not assignable to type 'Status' |
| Call an API method | Signature help and argument checks, for example on basket.getShipment() |
Typed hook families
SCAPI Shopper APIs run the same dw.ocapi.shop.* hooks as OCAPI, so one implementation gets the same types for both
| Hooks | Count | Typed parameters |
|---|---|---|
dw.ocapi.shop.basket.* | 35 | basket: dw.order.Basket, plus the request or response document. Covers the basket, items, coupons, payment instruments, billing address, and shipments |
dw.ocapi.shop.customer.* | 11 | customer: dw.customer.Customer, address names, and documents |
dw.ocapi.shop.order.* | 8 | order: dw.order.Order and the order response |
dw.ocapi.shop.auth.* | 3 | customer: dw.customer.Customer, authRequestType: dw.value.EnumValue |
dw.ocapi.shop.product.*, category.*, product_search.* | 6 | dw.catalog.Product, dw.catalog.Category, and the response document |
dw.order.calculate, calculateShipping, calculateTax, createOrderNo | 4 | basket: dw.order.Basket; createOrderNo returns a string |
dw.order.payment.*, return.*, shippingorder.* | 10 | dw.order.Order, Invoice, Return, and ShippingOrder |
dw.system.request.onRequest, onSession | 2 | Return type only |
dw.extensions.applepay.* | 7 | basket: dw.order.Basket, order: dw.order.Order |
Most hooks return dw.system.Status. Request and response documents (basketResponse, doc, and similar) are typed as plain objects, so any property you add is accepted
How the types are applied
Register the hook. The hooks.json your cartridge's package.json points to maps the hook name to a script. That registration is what links the file to a known signature
Export the function. Write exports.modifyGETResponse = function (basket, basketResponse) { … }, the module.exports.modifyGETResponse form or an arrow function. The function name must match the hook's last segment. A function that several hooks share, such as one beforePATCH for baskets and orders, takes the types of all of them, like dw.order.Basket | dw.order.Order
Edit as usual. The server adds the signature as JSDoc in its in-memory copy of the file. Your parameter names are kept, and types are applied by position
When types are not applied
- You wrote JSDoc. A
/** … */block above the export wins, so your own annotation is used instead - Other export shapes.
module.exports = { … }andexports.name = namedFunctionare not typed. Useexports.name = function (…) {} - Custom hooks. Your own hook names have no known signature. Add JSDoc or write the hook in TypeScript
- Hooks outside the list. For example the bare
dw.ocapi.shop.basket.beforePOST(the_v2variant is typed). Add JSDoc for those