Home > front end >  How to access Textencoder as a global instead of importing it from the util package?
How to access Textencoder as a global instead of importing it from the util package?

Time:04-25

I'm using Node v18.0.0 with TypeScript and it seems that the TextEncoder class is a global.

Unfortunately this code const textEncoder = new TextEncoder(); is invalid because it doesn't know about the class. I will have to import the util package to make it work, otherwise I get the error

Cannot find name 'TextEncoder'. Did you mean 'textEncoder'?ts(2552)

I'm using the packages "@types/node": "17.0.23" and "typescript": "4.6.3". The tsconfig.json file

{
  "compilerOptions": {
    "baseUrl": ".",
    "declaration": true,
    "esModuleInterop": true,
    "lib": [ "esnext" ],
    "module": "commonjs",
    "outDir": "build",
    "resolveJsonModule": true,
    "strict": true,
    "target": "es2019"
  },
  "include": [
    "./**/*.ts"
  ],
  "exclude": [
    "./build"
  ]
}

Does someone know how to fix this? Do I have to use some additional packages or modify my TS configuration?

Please let me know if you need more information!

CodePudding user response:

This looks like an inconsistency (at least) between the Node.js documentation (and runtime) and the @types/node package in DefinitelyTyped. This issue is very similar to this one with URL, which has since been fixed by adding a global declaration in url.d.ts. It may be worth opening an issue (and doing a PR).

As you say, TextEncoder is definitely a global (both the documentation and a quick test tell us that), but @types/node/globals.d.ts doesn't have it. @types/node/utils.d.ts does have it (as you indicated), and even has the comment "The TextEncoder class is also available on the global object." but...it's not (unlike URL, which [now] is).

If the code you're writing is Node.js-specific, I'd just do the import and not worry about it.

But if the code you're writing is supposed to target both Node.js and browsers, that's obviously not an option. One workaround mentioned in the URL issue thread is to add "dom" to your lib config setting, but that means all the DOM stuff is added to your global namespace.

Alternatively, until/unless the types are updated, you can declare the global yourself. In the root of your project:

whatever.d.ts:

import { TextEncoder as _TextEncoder } from "node:util";

declare global {
    var TextEncoder: typeof _TextEncoder;
}

You don't get useful popup information when you do new TextEncoder(, but it does work, and you do get useful information for its methods etc.

  • Related