Scopes & Types

How Digital Script resolves names and types, from the server scope and host objects to type annotations, for each loops, E4X and job step parameters

A Digital Script file sees what the server gives it: the Script API with its standard library, its own import calls and the modules it requires. The plugin types variables from annotations, loops and E4X, and reports names the server won't have

Browser and Node.js globals such as setTimeout, console and java are warnings, since the server has none of them. A typeof test and Promise are fine, and console calls have a fix to dw.system.Logger

The server scope

.ds files and server .js files resolve names against the bundled Script API typings and your project's modules. The typings declare the standard library the server runs, so the IDE's ES libraries such as lib.es5.d.ts stay out. Server .ts files keep them, without the browser libraries. A script also sees the same script in the other cartridges, as an override does, see Overrides

  • Map and Set resolve, as the Script API declares them
  • Browser and Node.js names such as window, document, fetch and setTimeout don't resolve, and are reported as host objects
  • Client .js files keep the IDE's usual browser scope

Host objects

Host object B2C Commerce does not have is a warning on the browser, Node.js and Java names the server lacks, such as 'setTimeout' is not available on B2C Commerce:

setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, console, process, Buffer, window, document, XMLHttpRequest, fetch, Packages, java, JavaAdapter and JavaImporter

Not reportedExample
A typeof feature testif (typeof setInterval === 'function')
A name your own code declares, such as a polyfillAnother script's polyfill counts once the file imports that script
PromisePromise.resolve(1)

The Use dw.system.Logger.debug fix turns a console call into a Logger call of the same level: log, debug and trace become debug, and info, warn and error keep theirs

A weak warning comes from the same check: 'module' does not exist in templates in <isscript> code, and the same for exports

Unresolved names and types

CheckMessageWhere
Name that nothing declaresCannot find name 'unknownCall'Scripts and templates
Type annotation that names no typeCannot find type 'Strin'Scripts
B2C Commerce class the script does not import'HashMap' is a class of dw.util that this script does not import, see Missing importsScripts

All three are errors in the Unresolved name, type or script path color, red with a wave in every bundled scheme. In Digital Script they replace the IDE's weak unresolved warning, and client .js files keep it. An importScript path that names no script takes the same color

Name that nothing declares skips an assignment that creates a global, a typeof operand, host objects, and names in comments and with blocks. In templates it also skips the names any <isset> in the project sets. A noinspection JSUnresolvedReference comment still silences it, and while the IDE indexes the IDE's own warning shows instead

Block const

On B2C Commerce a const declared in a block, such as an if, a try or a loop, holds for the whole function. The plugin scopes it the same way

On B2C Commerce a const declared in a block holds for the whole function. A read after the block resolves, is typed and completes, and Cmd+Click opens the declaration
  • A read after the block resolves, is typed and completes, and the constant isn't reported as unresolved or unused
  • Cmd+Click, Find Usages and Rename cover every read in the function
  • Convert to let and Convert to const aren't suggested while 'let' or 'const' in server code runs, which is on by default. With that check off or without a license, Convert to const isn't suggested inside a loop, where the const would keep its first value, or for a name the function declares twice
  • Duplicate declaration doesn't report a var that sibling blocks each declare with their own value

To write var instead, see let and const

Type annotations

Rhino type annotations type variables, parameters and return values:

cartridge/scripts/catalog/Price.ds
importPackage(dw.catalog);
importClass(dw.order.Basket);

function product(id : String) : Product {
    return ProductMgr.getProduct(id);
}

var basket : Basket = null;
var item = product('sku-1');
AnnotationType
String, Number, Booleanstring, number, boolean
A class the file imports, such as Product after importPackage(dw.catalog)dw.catalog.Product
A qualified class, such as dw.order.BasketThat class
Object, Date, ArrayThe JavaScript type

A call of a function with a return annotation gets that type, so item above is a dw.catalog.Product. To switch between annotations and JSDoc, see Intentions

Loop types

A loop variable gets the element type of what it iterates:

LoopVariable type
for each (var a in pli) over a Script API collectionThe element, such as ProductLineItem
for each (var b in pli.iterator())The element
for (var i of pli)The element
for each (var c in map) over a dw.util.HashMapThe value type
for (var d in map)The key type
for each (var f in [1, 2])number
for each (var g in {a: 1, b: 'x'})number or string
for each (var h in xml)XML
for each (var k : String in pli)The annotation, string

Quick documentation on each says what the loop yields, such as "Iterates the values of the map. for (k in m) iterates its keys."

E4X types

ExpressionType
<feed/>, <?xml version="1.0"?><feed/>, XML(s)XML
<></>, XMLList(s), x.@id, x..item, x.*, x.ns::name, x.(@id == '1'), x.itemXMLList
x[0]XML

After feed. completion offers the element names of the file's XML literals, then the XML methods. After @ it offers only the attribute names. E4X members are never reported as unresolved

Parameters the server passes

FunctionTyped from
A pipelet's execute(pdict)The header keys, then dw.system.PipelineDictionary, see Pipelets & Script Nodes
A hook function named in hooks.jsonThe hook's parameters by position. A function several hooks share gets the union
A step function named in steptypes.jsonThe step kind, see below
Step functionParameters
function, before-step-function, total-count-function, read-function, before-chunk-function(Object, dw.job.JobStepExecution)
process-function(item, Object, dw.job.JobStepExecution)
write-function(dw.util.List, Object, dw.job.JobStepExecution)
after-chunk-function, after-step-function(boolean, Object, dw.job.JobStepExecution)

A JSDoc @param wins over both. A script-module-step without a function runs execute. These types wait until indexing ends

.ds, .js and .ts together

  • require('./helper') finds helper.js, then helper.ds, then helper.json, as the server does
  • A .ts source deploys as .js, so require finds foo.ts as foo. A .js beside its .ts wins
  • A .d.ts beside a .ds or .js module types what require returns
  • require of a .ts with ES exports gives the whole namespace object, never the default alone
  • In a server .ts file, a default or namespace import of a .ds or .js module gives its module.exports

Name that changes when a .ts source deploys catches what breaks on upload:

MessageFix
Price.js is in the same folder, and both deploy as Price.jsNone
The server has no .ts files: 'helpers/price' names the deployed moduleRemove '.ts'
The Babel build cannot compile 'export =': assign module.exportsAssign module.exports
The Babel build cannot compile 'import = require()': use constUse const

A .js built from its .ts, with __esModule or a //# sourceMappingURL= comment, isn't reported as a clash

On this page