electron: electron.d.ts does not work with @types/node v13.1.0

Preflight Checklist

  • I have read the Contributing Guidelines for this project.
  • I agree to follow the Code of Conduct that this project adheres to.
  • I have searched the issue tracker for an issue that matches the one I want to file, without success.

Issue Details

  • Electron Version:
    • 7.1.7
  • Operating System:
    • macOS 10.14
  • Last Known Working Electron version:
    • N/A

Expected Behavior

Can compile successfully the TypeScript code

Actual Behavior

Compilation error

main/window.ts:14:5 - error TS2339: Property 'removeAllListeners' does not exist on type 'BrowserWindow'.

14 win.removeAllListeners();
       ~~~~~~~~~~~~~~~~~~

node_modules/electron/electron.d.ts:1655:31 - error TS2689: Cannot extend an interface 'NodeJS.EventEmitter'. Did you mean 'implements'?

1655   class BrowserWindow extends NodeJS.EventEmitter {
                                   ~~~~~~

EDIT: Added entire compile error messages thanks to https://github.com/electron/electron/issues/21612#issuecomment-568691944

To Reproduce

Try to compile following code with the latest TypeScript compiler and latest @types/node package.

import { BrowserWindow } from 'electron';
const win = new BrowserWindow();
win.removeAllListeners();

Package versions:

  • typescript: 3.7.4
  • @types/node: 13.1.0

Screenshots

Nothing

Additional Information

I have investigated this issue and found the cause.

@types/node v13 has breaking change affecting NodeJS.EventEmitter from v12. It was changed from class to interface. Now, EventEmitter can only be extended by interfaces. I confirmed electron.d.ts worked fine with @types/node v12. The change is here:

https://github.com/DefinitelyTyped/DefinitelyTyped/commit/c47a34ead1637f6f34e7d630dc88ea3f6e5562cb#diff-a2f9a5377787f7084c7f52b20c0108cfR540

However, classes such as BrowserWindow in electron.d.ts try to extend EventEmitter so it is causing this issue.

May be related to #21475

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 34
  • Comments: 81 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Why is this closed? This still doesn’t work

@marcschroeder If you don’t need Node 13 typings, you can add @types/node@12 to your dependencies.

e.g. npm i --save-dev @types/node@12 or yarn add -D @types/node@12

Run npm install --save --save-exact @types/node@^12.12.6. It works afterward (even with Electron v8.2.5).

As it is said repeatedly in this issue thread, the fix for electron.d.ts for Node v13 is already there. I had made a PR and it was merged. But Node.js integrated to Electron is still v12 even in Electron v9. So using @types/node@12 is proper and the fix is not included in Electron v9. You should use @types/node@12.

The @types/node for node 13 also result in the following type error:

Cannot extend an interface 'NodeJS.EventEmitter'. Did you mean 'implements'?

More

https://github.com/DefinitelyTyped/DefinitelyTyped/commit/c47a34ead1637f6f34e7d630dc88ea3f6e5562cb#r36559684

Same issue for me when using instructions from : https://www.electronforge.io/templates/typescript-template

I was able to work around this for now by doing the follow in the initialized directory:

npm install @types/node --save

then editing package.json changing

"dependencies": { "@types/node": "^13.1.4", "electron-squirrel-startup": "^1.0.0" }

to

"dependencies": { "@types/node": "12.12.6", "electron-squirrel-startup": "^1.0.0" }

and finally running

npm install && npm start

It’s expected as Electron v7 comes with node v12, so use the most recent @types/node v12.

Could a maintainer of Electron (or someone else who knows) maybe clarify what the release cycle of type definitions looks like? There were multiple releases for Eletron 8.x in the past weeks, none of which shipped with the updated definitions. Does it mean they will ship with Electron 9 (is this considered a breaking change)? Or is this update dependent on something else?

@j-o-d-o If your using yarn, add to package.json this:

 "resolutions": {
    "@types/node": "12.12.6"
  },

Otherwise, it might resolve version 13 implicitly by some deps

Force all references in your package.json and yarn.lock to use @types/node 12.21.12. This is an unacceptable but hopefully temporary scenario There’s a few people trying to act as though the problem is electron 7 uses node 12 and not 13. They’re just plain wrong. The problem is the use of extends vs implements keywords on classes/interfaces. Again you have version ranges (for example, redux says @types/node:^8) On Wed, Dec 25, 2019, 8:33 AM Cyrus Frost @.***> wrote: Is there a temporary workaround to this? I’m unable to compile a typescript project due to the error listed in OP. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#21612?email_source=notifications&email_token=AAQGPCWYY4R2NEQ6OW23OYLQ2NOJLA5CNFSM4J63DZ52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHULURI#issuecomment-568900165>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQGPCTIGMVJ4QSYKYF7TKTQ2NOJLANCNFSM4J63DZ5Q .

This workaround works! Thanks! Minor correction: the @types/node version in package.json should be 12.12.21 instead of 12.21.12.

same problem even with electron v9.0.0

Workaround:

  • Go back to Electron 6.x.x (don’t blame me, I’m just a guy trying to find a “solution” here)
  • npm install
  • open package-lock.json
  • search for "@types/node":
  • find the entry under electron (the values I show below are for 6.1.9)
      "requires": {
        "@types/node": "^10.12.18",
        "electron-download": "^4.1.0",
        "extract-zip": "^1.0.3"
      },
      "dependencies": {
        "@types/node": {
          "version": "10.17.17",
          "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz",
          "integrity": "sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q==",
          "dev": true
        }
      }
  • Modify the requires reference, remove the dependencies block (and the comma that was between requires and dependencies)
      "requires": {
        "@types/node": "*",
        "electron-download": "^4.1.0",
        "extract-zip": "^1.0.3"
      }
  • In the file system remove node_modules/electron/node_modules

It works afterward (even with Electron v8.2.5).

Of course it works this way. The point of this issue is that other deps used in the project require node@^13.

Force all references in your package.json and yarn.lock to use @types/node 12.21.12. This is an unacceptable but hopefully temporary scenario

There’s a few people trying to act as though the problem is electron 7 uses node 12 and not 13. They’re just plain wrong. The problem is the use of extends vs implements keywords on classes/interfaces. Again you have version ranges (for example, redux says @types/node:^8)

On Wed, Dec 25, 2019, 8:33 AM Cyrus Frost notifications@github.com wrote:

Is there a temporary workaround to this? I’m unable to compile a typescript project due to the error listed in OP.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/electron/electron/issues/21612?email_source=notifications&email_token=AAQGPCWYY4R2NEQ6OW23OYLQ2NOJLA5CNFSM4J63DZ52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHULURI#issuecomment-568900165, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQGPCTIGMVJ4QSYKYF7TKTQ2NOJLANCNFSM4J63DZ5Q .

I still have this problem. I can’t keep my @types/node to 12.12.21 for long time. could you please reopen the issue and fix it?

Fine, mea culpa - it’s not your fault. Nevertheless, the attempt to resolve this issue by the electron team is woefully inadequate.

It seems that what happened is that electron@8.0 now specifies specifically @types/node 12 in its package json - but otherwise makes no attempt to use implements as opposed to extends (which would have worked for @types/node 12 or 13) , and consequently yarn made a node_modules/@types/node directory underneath the node_modules/electron directory. The problem is if some other library called for @types/node 13 or * (which brings in ^13), typescript only uses one of the two folders (not both).

I ended up with the following folder structure and at compile time typescript only accessed one @types/node (the root one which is 13.x)

node_modules
> @types
> > ...
> > node (13.x)
> electron (8.0.0)
> > node_modules
> > > @types
> > > > node (12.x)
> ...

Downgrading to version 12.12.6 helped.

Looks like we got thoughtful TypeSript and semver versioning expert here ==> @amirburbea

The problem is the use of extends vs implements keywords on classes/interfaces.

Electron npm module is shipped with @types/node@^12.0.12 at the moment so it’s totally fine that they do extends NodeJS.EventEmitter since NodeJS.EventEmitter is a class in @types/node prior v13.

It’s expected as Electron v7 comes with node v12, so use the most recent @types/node v12.

No @vladimiry . That’s not how it works

Electron even has automated test added for verifying that major versions of bundled node and @types/node got matched, see https://github.com/electron/electron/blob/f426ad1b5914295f9684036fb55f918c1b074900/spec-main/types-spec.ts

there is no direct tie between @types/node and the version of nodejs

There’s a few people trying to act as though the problem is electron 7 uses node 12 and not 13.

For curious persons, checking @types/node and nodejs versions correlation:

You can clone the https://github.com/DefinitelyTyped/DefinitelyTyped and execute git log -L 1,1:types/node/index.d.ts --pretty=oneline to see that commit message corresponds to first-line/header of the types/node/index.d.ts file change. So this pretty much indicates that version of @types/node corresponds to nodejs version.

c47a34ead1637f6f34e7d630dc88ea3f6e5562cb feat(node): v13 (#40927)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 12.12
+// Type definitions for non-npm package Node.js 13.1
a91a9a49ded5dd536a4bb0d2098eb1b0de1eadcd feat(node): v12.12 (#39914)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 12.11
+// Type definitions for non-npm package Node.js 12.12
cbe21d594a3b24fd1b93719958bc90ab6007ac51 feat(node): v12.11 (#39116)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 12.7
+// Type definitions for non-npm package Node.js 12.11
3f6627ea70b804317b90c0212b2055eff0a67a6f feat(node): v12.7 (#37217)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 12.6
+// Type definitions for non-npm package Node.js 12.7
4db4c26549c7edd452c46492f3421d5dce3200b0 feat: node v12.5 (#36562)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 12.0
+// Type definitions for non-npm package Node.js 12.6
18b13d1f4a6830861bf4f693a706dcde4aa8b21f feat(node): v12 (#34952)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 11.13
+// Type definitions for non-npm package Node.js 12.0
e6625ba155c7529e8bfb751a23b0d12bb8fe1ec5 feat(node): v11.13

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 11.12
+// Type definitions for non-npm package Node.js 11.13
923fe86451333613c015358a7447ed914945427f feat(node): v11.12 (#33967)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 11.11
+// Type definitions for non-npm package Node.js 11.12
bac137341280d31ee0f8159ddad66b0fa144e5fa feat(node): v11.11

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 11.10
+// Type definitions for non-npm package Node.js 11.11
80fb3119f40c6b70e4a9632887980036e36f6b2b feat(node): v11.10

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for non-npm package Node.js 11.9
+// Type definitions for non-npm package Node.js 11.10
608c146d8982a2ff7307f0a3bdddd6d55cb1a63e Mark non-npm packages

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 11.9
+// Type definitions for non-npm package Node.js 11.9
c8dadc971b8524704c4b39243780e294d7a15f12 feat(node): enable strict null checks and add SharedArrayBuffer

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 11.6
+// Type definitions for Node.js 11.9
e69abd8af13b4dd17259e72898b118102993915d feat(node): v11.6

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.12
+// Type definitions for Node.js 11.6
df80e09009547e5556c09a16f3c715ecf9aff325 feat(node): 10.12 (#29689)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.11
+// Type definitions for Node.js 10.12
352f2a6a39758bead6182a0d04bcf0b8d7c7a381 chore(node): apply lint

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.11.x
+// Type definitions for Node.js 10.11
e17d39e6b09a1e44d7dd69fa22b3da42c7156948 feat(node): 10.11

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.10.x
+// Type definitions for Node.js 10.11.x
9061b19a3c7d676fc4aeacc825ab7790edad13c6 types(node): add changes from 10.10 (#28918)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.9.x
+// Type definitions for Node.js 10.10.x
374598de675780b1312912d43dff88f9fbfcf0d8 [node] Add http[s] request/get variants for 10.9.0 (#28193)

diff --git a/types/node/index.d.ts b/types/node/index.d.ts
--- a/types/node/index.d.ts
+++ b/types/node/index.d.ts
@@ -1,1 +1,1 @@
-// Type definitions for Node.js 10.7.x
+// Type definitions for Node.js 10.9.x
3c8f15080c5728847c627ba07a623276ef1869ab add timeout to http.AgentOptions (#21346 
...

Regarding @types/node v13. You could see that what they do there with like 160 d.ts files of different libraries to make them compatible with @types/node@^13 is replacing

declare class SomeClass extends NodeJS.EventEmitter

with

import { EventEmitter } from 'events'; 
declare class SomeClass extends EventEmitter { 

So @electron will probably follow the same way one day when they move to @types/node@^13.

CC @MarshallOfSound

guys this is closed issue and nobody will look at it. I oped another issue please add your comments on that.

I’ve got another, pre-2.9-compatible one at electron/typescript-definitions#164, but I would only use it if old Typescript compatibility is very important. As I commented on electron/typescript-definitions#163, the numbers we see from VS and VS Code indicate that it’s probably not.

Any ideas anyone?

I have raised a pull request at https://github.com/electron/typescript-definitions/pull/163 for this issue.

Thank you for your support @andrewbranch! I finally could fix electron.d.ts as follows without breaking change. I confirmed tsc compiled successfully.

https://gist.github.com/rhysd/c8d68f0399a84a5383aee67857642852

I will try to fix auto-generation logic.

Sorry, I should have tried the code I said before saying it. This is what I meant @rhysd:

image

However, note that this makes EventEmitter appear global, which may not be desirable. I think declare global is a better option all around.


Where is the events global value defined?

I was mistaken—I realized that events is globally available in node at runtime, like other built-in modules, and assumed it had a type declaration, but it does not.

I think it’s safe to move to 3.0 as a baseline for electron’s use of typescript. That would be 18 months old already. (TS3.0 released July2018, TS 2.8 was March2018 - not even a huge lag time between them)