'How to set global.TextDecoder in jest for jsdom if node's util.TextDecoder is type mismatch?

Try to use jsdom with Jest in an NX repo (typescript/angular) and I get the problem that TextEncoder and TextDecoder are not present. I get the same result whether I set the jest testEnvironment to 'jsdom' or 'node' and with versions of node from 10 to 16)

So, following solutions other people posted (thanks!), I imported them in my test-setup.ts from node and set them on the node global object:

import 'jest-preset-angular/setup-jest'
import { TextEncoder, TextDecoder } from 'util';

global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;

This seems to work for TextEncoder, but not for TextDecoder:

   libs/xplat/features/test-setup.ts:10:1 - error TS2322: Type 'typeof TextDecoder' is not assignable to type '{ new (label?: string | undefined, options?: TextDecoderOptions | undefined): TextDecoder; prototype: TextDecoder; }'.
      The types of 'prototype.decode' are incompatible between these types.
        Type '(input?: ArrayBufferView | ArrayBuffer | null | undefined, options?: { stream?: boolean | undefined; } | undefined) => string' is not assignable to type '(input?: BufferSource | undefined, options?: TextDecodeOptions | undefined) => string'.
          Types of parameters 'input' and 'input' are incompatible.
            Type 'BufferSource | undefined' is not assignable to type 'ArrayBufferView | ArrayBuffer | null | undefined'.
              Type 'ArrayBufferView' is not assignable to type 'ArrayBufferView | ArrayBuffer | null | undefined'.
                Type 'ArrayBufferView' is missing the following properties from type 'DataView': getFloat32, getFloat64, getInt8, getInt16, and 17 more.

    10 global.TextDecoder = TextDecoder;

Is there a different TextDecoder I should use - in particular, is there one somehow bundled with jest's jsdom which I'm just not seeing how to use?

In case it helps, here some versions (from my most recent package.json):

"devDependencies": {
    "@angular-devkit/architect": "^0.1301.2",
    "@angular-devkit/build-angular": "<=13.0.2",
    ...
    "@nrwl/angular": "13.4.6",
    "@nrwl/cli": "13.4.6",
    ...
    "@nrwl/jest": "13.4.6",
     ...
    "@types/core-js": "^2.5.5",
    "@types/jest": "^27.0.2",
    "@types/jsdom": "^16.2.14",
    "@types/node": "14.14.33",
    "@types/whatwg-url": "^8.2.1",
    "@typescript-eslint/eslint-plugin": "~5.3.0",
    "@typescript-eslint/parser": "~5.3.0",
   ...
    "jest": "27.2.3",
    "jest-jasmine2": "^27.4.6",
    "jest-preset-angular": "11.0.0",
    "jsdom": "^19.0.0",
    "ng-mocks": "^12.5.1",
    ...
    "ts-jest": "27.0.5",
    "typescript": "~4.4.3",
    "util": "^0.12.4",
    "whatwg-url": "^11.0.0"
  },


Solution 1:[1]

I managed to get rid of the error by first coercing the global object to any then assigning the TextDecoder:

import { TextEncoder, TextDecoder } from "util";
(global as any).TextEncoder = TextEncoder;
(global as any).TextDecoder = TextDecoder;

I know it is not the best way of accomplishing the desired goal and would generally be considered bad practice but, as this is just for Jest's testing I think it should be ok.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MakingStuffs