"ReferenceError: structuredClone is not defined" using jest with nodejs & typescript

Viewed 382

I'm running tests with jest in a simple NodeJS app that uses typescript. My test is throwing an error: ReferenceError: structuredClone is not defined.

I'm not getting any linter errors and the code compiles fine normally.

  const variableForValidation = structuredClone(variableForValidationUncloned);

package.json:

  "dependencies": {
    ...
  },
  "devDependencies": {
    "@types/jest": "^29.0.0",
    "@types/node": "^18.7.15",
    "@typescript-eslint/eslint-plugin": "^5.36.1",
    "@typescript-eslint/parser": "^5.36.1",
    "eslint": "^8.23.0",
    "jest": "^28.0.1",
    "nodemon": "^2.0.19",
    "serverless-plugin-typescript": "^2.1.2",
    "ts-jest": "^28.0.8",
    "ts-node": "^10.9.1",
    "typescript": "^4.8.2"
  }

This github issue suggests to me that the issue has been resolved: https://github.com/facebook/jest/issues/12628 - or perhaps I'm misunderstanding?

I've seen a similar Stack question but using Mocha: mocha not recognizing structuredClone is not defined

3 Answers

I couldn't figure it out, so I set my own global:

// globals.ts
if(!global.structuredClone){
    global.structuredClone = function structuredClone(objectToClone: any) {
          const stringified = JSON.stringify(objectToClone);
          const parsed = JSON.parse(stringified);
          return parsed;
        }
}
// entry point of app, eg index.ts:
import './globals.ts'
// ...

I think it might be because the target in my tsconfig is converting my typescript files to a javascript/node version before structuredClone was added?

For the same error, having the code below in the test file fixed the issue for me.

global.structuredClone = (val) => JSON.parse(JSON.stringify(val))

Reference

structuredClone was added in Node 17.

If you can't update, the JSON hack (stringify then parse) works, but has some shortcommings that might be relevant to you:

  • Recursive data structures: JSON.stringify() will throw when you give it a recursive data structure. This can happen quite easily when working with linked lists or trees.
  • Built-in types: JSON.stringify() will throw if the value contains other JS built-ins like Map, Set, Date, RegExp or ArrayBuffer.
  • Functions: JSON.stringify() will quietly discard functions.
Related