TypeScript Keywords
TypeScript keywords use exactly the same Keyword API as JavaScript: each keyword is an exported async function receiving the same arguments, executed on the Node.js agent. The only difference lies in the project setup, described on this page: the Node.js agent executes CommonJS JavaScript, so the TypeScript sources are compiled into the project’s keywords/ directory as part of your build.
If you are new to keyword development, read the Keyword Development page first.
Project setup
A typical project keeps the TypeScript sources in src/ and the tests in tests/:
package.json tsconfig.json src/ └── MyKeywords.ts TypeScript sources tests/ └── MyKeywords.test.ts local tests keywords/ compiled output (generated by the build)
In package.json, declare typescript and the type-checking/test tooling alongside step-node-agent as development dependencies, and compile as part of the build and test scripts:
{
"scripts": {
"build": "tsc --build",
"test": "npm run build && node --import tsx --test \"tests/**/*.test.ts\""
},
"devDependencies": {
"step-node-agent": "3.30.0",
"tsx": "latest",
"typescript": "latest",
"@types/node": "latest"
}
}In tsconfig.json, the module option must be set to commonjs and outDir to the keywords directory:
{
"compilerOptions": {
"target": "es2022",
"module": "commonjs",
"rootDir": "./src",
"outDir": "keywords",
"types": ["node"]
},
"include": ["./src/**/*.ts"]
}Keyword declaration
Keywords are declared as exported async functions; as in JavaScript, the export name is the keyword name as registered in Step:
export async function MyKeyword(input: any, output: any, session: any, properties: any): Promise<void> {
const result = await doSomething(input?.param)
output.add('result', result)
}Refer to the Keyword API page for the full documentation of the keyword arguments, outputs, attachments, measurements, hooks, and sessions — the JavaScript samples apply as-is.
Local testing
Keywords can be tested locally with the runner utility, for instance using the Node.js built-in test runner:
import { describe, it, after } from 'node:test'
import assert from 'node:assert'
import stepNodeAgent from 'step-node-agent'
const runner = stepNodeAgent.runner({})
describe('MyKeyword', () => {
after(() => runner.close())
it('should execute without error', async () => {
const output = await runner.run('MyKeyword', { param: 'value' })
assert.ok(output.error == null, `Keyword failed: ${output.error}`)
})
})Since the agent and the local runner both consume the compiled files in keywords/, make sure to run the build before testing locally (as the test script above does) and before packaging or deploying the project to Step.