Types & the dw API
The complete dw.* API is typed out of the box, and your own metadata becomes TypeScript types automatically
The SFCC language server runs a real TypeScript language service for every server-side script - whether the file is .js, .ts, or .ds. That is what powers completion, hover, signature help, and diagnostics with genuine type awareness instead of text matching. You write ordinary SFCC code; the engine treats it as a typed program.
The dw.* API, Fully Typed
The complete Salesforce B2C Commerce API surface ships with the extension as TypeScript definitions. Every class, method, property, and constant under dw/* is typed and documented.
var ProductMgr = require('dw/catalog/ProductMgr');
var BasketMgr = require('dw/order/BasketMgr');
var product = ProductMgr.getProduct('my-product-id');
product. // ← full completion: getName(), getPriceModel(), custom, …Because the API is fully typed, you also get:
- Hover docs with the official description, parameter types, and return type.
- Signature help while filling in arguments.
- Errors when you call a method that does not exist or pass the wrong type.
See Code Completion, Hover & Signature Help, and Diagnostics & Quick Fixes for each of these in detail.
Types Generated From Your Project
This is what makes the engine SFCC-specific rather than a generic JS service. As it indexes your workspace, the language server reads your metadata XML and generates TypeScript types from it - so your custom attributes and objects are typed.
Custom attributes on system objects
A type-extension in your metadata XML adds attributes to a standard object:
<type-extension type-id="Product">
<custom-attribute-definitions>
<attribute-definition attribute-id="ecoFriendly">
<type>boolean</type>
</attribute-definition>
</custom-attribute-definitions>
</type-extension>After indexing, those attributes appear in completion on the custom property:
var product = ProductMgr.getProduct('p1');
product.custom. // ← completion includes ecoFriendly (boolean)Custom objects
A custom-type definition makes CustomObjectMgr results typed for that type's attributes:
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var record = CustomObjectMgr.getCustomObject('MyLog', key);
record.custom. // ← completion for the attributes you defined in XMLThese types are generated in memory from the XML in your workspace and refresh as you edit metadata - there is no file to commit and no generator to run.
Typed Hook Implementations
Scripts registered as hooks in hooks.json are typed against the known hook signatures. An exports.calculate = function (basket) { … } in a dw.order.calculate hook gets basket typed as dw.order.Basket and the return typed as dw.system.Status - with no annotations from you.
// cartridge/scripts/hooks/calculate.js - registered for dw.order.calculate
exports.calculate = function (basket) {
basket. // ← typed as dw.order.Basket
return new (require('dw/system/Status'))(/* ... */);
};