Skip to content

node: [fix] node buffers have a constructor property#28900

Merged
jessetrinity merged 2 commits intoDefinitelyTyped:masterfrom
ljharb:buffer_constructor
Sep 21, 2018
Merged

node: [fix] node buffers have a constructor property#28900
jessetrinity merged 2 commits intoDefinitelyTyped:masterfrom
ljharb:buffer_constructor

Conversation

@ljharb
Copy link
Contributor

@ljharb ljharb commented Sep 14, 2018

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Test the change in your own code. (Compile and run.)
  • Add or edit tests to reflect the change. (Run with npm test.)
  • Follow the advice from the readme.
  • Avoid common mistakes.
  • Run npm run lint package-name (or tsc if no tslint.json is present).

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: new Buffer('').constructor === Buffer, in every node version ever
  • Increase the version number in the header if appropriate.
  • If you are making substantial changes, consider adding a tslint.json containing { "extends": "dtslint/dt.json" }.

@typescript-bot typescript-bot added Popular package This PR affects a popular package (as counted by NPM download counts). The Travis CI build failed labels Sep 14, 2018
@typescript-bot
Copy link
Contributor

typescript-bot commented Sep 14, 2018

@ljharb Thank you for submitting this PR!

🔔 @parambirs @tellnes @WilcoBakker @octo-sniffle @smac89 @Flarna @mwiktorczyk @wwwy3y3 @DeividasBakanas @kjin @alvis @eps1lon @Hannes-Magnusson-CK @jkomyno @ajafff @hoo29 @n-e @BrunoScheufler @mohsen1 @KSXGitHub @a-tarasyuk @islishude @r3nya @eyqs @ZaneHannanAU @ThomasdenH @matthieusieben - please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead.

@typescript-bot
Copy link
Contributor

@ljharb The Travis CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@ljharb
Copy link
Contributor Author

ljharb commented Sep 14, 2018

Looks like the node types prior to v9 lack types for the NodeBuffer constructor itself - I'll revert those, and only include the v9+ type fix.

@Flarna
Copy link
Contributor

Flarna commented Sep 16, 2018

I'm not sure what this change is needed for. What's wrong with the new APIs defined below declare var Buffer? Could you add a test to show the use case enabled by this?
Why only NodeJS 9 and not latest nodejs?

@ljharb
Copy link
Contributor Author

ljharb commented Sep 16, 2018

@Flarna i have a place where i do obj.constructor.isBuffer, and this was erroring without this change. I only included the fix for v9 because the older versions don’t seem to have types for the constructor (#28900 (comment))

I’ll try to add a test.

@Flarna
Copy link
Contributor

Flarna commented Sep 16, 2018

@ljharb With latest NodeJs I mean the file types\node\index.d.ts.
I wonder a little about your usecase. Why not using the static API Buffer.isBuffer()?
If Buffer definition would be changed to class with static methods your usage wont work also as far as I know as typeof <some Buffer instance>.constructor would be of type Function.

@ljharb
Copy link
Contributor Author

ljharb commented Sep 16, 2018

Because if i do that, bundlers include an entire Buffer polyfill - see ljharb/qs#39.

As for the type, for any builtin T besides Function, typeof new T().constructor should always be T - if it’s only Function, then that’s a bug in the type system.

@Flarna
Copy link
Contributor

Flarna commented Sep 16, 2018

ok understood.

As for the type, for any builtin T besides Function, typeof new T().constructor should always be T - if it’s only Function, then that’s a bug in the type system.

Seems so yes, see microsoft/TypeScript#3841

@ljharb
Copy link
Contributor Author

ljharb commented Sep 16, 2018

In that case, do you suggest a different approach? This is a pretty basic part of JS to have been mistyped for this long :-/

@Flarna
Copy link
Contributor

Flarna commented Sep 17, 2018

I don't have a different approach.
At first I haven't understood why this is needed at all, then I thought about converting Buffer to class - assuming that this solves your problem. But it turned out it doesn't and googling routed me to above typescript issue. I haven't read all comments there, not sure if there is something better we could use here.

Copy link
Contributor

@Flarna Flarna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adapt also latest NodeJs typings (file types\node\index.d.ts)

@ljharb
Copy link
Contributor Author

ljharb commented Sep 19, 2018

@Flarna thanks, updated (i missed it because i assumed there'd be a v10 folder)

@typescript-bot typescript-bot added Owner Approved A listed owner of this package signed off on the pull request. Merge:Express and removed Awaiting reviewer feedback labels Sep 19, 2018
@typescript-bot
Copy link
Contributor

A definition owner has approved this PR ⭐️. A maintainer will merge this PR shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped!

@jessetrinity
Copy link
Contributor

@ljharb Did you still want to add a test to this?

@mohsen1
Copy link
Contributor

mohsen1 commented Sep 19, 2018

Why we have EventEmitter as a class but not Buffer?

TypeScript enforces new for classes. Note that real classes are not callable without new in runtime.

But Node "class"es are not real classes and are just plain functions.

We have to decide if we want to use class for Node classes or not. if we use class, this change will be unnecessary.

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

@jessetrinity oh right, i'd forgotten - is there an easy way to just run the tests for this one package without having to run them for the entire repo?

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

But Node "class"es are not real classes

Note that JS doesn't have any sort of "real classes", just class, which is conceptually and functionally identical to ES5 newed constructor functions - anything that's intended to be newed is a "class", altho class produces uncallable constructors (ie, they require new).

@mohsen1
Copy link
Contributor

mohsen1 commented Sep 20, 2018

TypeScript throws an error for calling classes without new which is a runtime error if target is defined using the class keyword (isn't "actual class" a good name for this case?)

Currently EventEmitter is declared as a class which will produce a TS error for calling it without new, although it's fine in Node.js runtime because its not defined with a class keyword.

@Andy-MS
My question is, should we stop using class for other Node.js "classes" until Node changes its code to use the class keyword?

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

In that case then anything not declared with class probably shouldn't be typed as one, no

@ghost
Copy link

ghost commented Sep 20, 2018

require("events")() fails for me with: TypeError: Cannot set property 'domain' of undefined.

Even if that did work, I think the simplicity of declaring something as a class outweighs the ability to omit the new keyword even if that were supported.

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

@Andy-MS i'd say if it worked, then typing it to include that would be critical; if it doesn't work, then clearly it's acting as a class even if it can be .called on something.

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

@jessetrinity fwiw npm install failed for me on node 10 on my mac; is there a specific version of node that this repo requires to work? (i'll rebase and try again, just in case)

@Flarna
Copy link
Contributor

Flarna commented Sep 20, 2018

Why we have EventEmitter as a class but not Buffer?

I think mostly because no one issues a PR to improve this. I can remember several PRs to change this and that interface to a class to fix concrete issues but no PR like "use classes where applicable". I think that older typescript versions (maybe <2) had also some limitations regarding merging of interfaces, classes and namespaces but I can't remember in detail.

@Flarna
Copy link
Contributor

Flarna commented Sep 20, 2018

Currently EventEmitter is declared as a class which will produce a TS error for calling it without new, although it's fine in Node.js runtime because its not defined with a class keyword.

NodeJs doc tells it's a class.
@mohsen1 What is the real world usecase to call EventEmitter without new? Sure, for JS point of view it's fine but quite a lot is allowed from JS point of view where typescript tells it's not allowed.

@jessetrinity
Copy link
Contributor

@ljharb Node 10 should be fine. Normally you can run tests from types/foo but in the case of Node you should run the whole things.

Any details on how it is failing? I will have to ask around about Mac.

@ljharb
Copy link
Contributor Author

ljharb commented Sep 20, 2018

@jessetrinity compilation errors:

Details
$HOME/.node-gyp/10.10.0/include/node/openssl/ossl_typ.h:107:16
: note: forward declaration of 'struct dsa_st'
typedef struct dsa_st DSA;
               ^
../vendor/libssh2/src/openssl.c:133:14: error: incomplete definition of type 'struct dsa_st'
    (*dsactx)->q = BN_new();
    ~~~~~~~~~^
$HOME/.node-gyp/10.10.0/include/node/openssl/ossl_typ.h:107:16: note: forward declaration of 'struct dsa_st'
typedef struct dsa_st DSA;
               ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [Release/obj.target/libssh2/vendor/libssh2/src/openssl.o] Error 1
gyp

ERR! build error
gyp
ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack
at ChildProcess.onExit ($HOME/.nvm/versions/node/v10.10.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR!
stack     at ChildProcess.emit (events.js:182:13)
gyp
ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:240:12)
gyp
ERR! System Darwin 17.7.0
gyp
ERR! command "$HOME/.nvm/versions/node/v10.10.0/bin/node" "$HOME/.nvm/versions/node/v10.10.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "build" "--fallback-to-build" "--module=$HOME/airlab/repos/DefinitelyTyped/node_modules/nodegit/build/Release/nodegit.node" "--module_name=nodegit" "--module_path=$HOME/airlab/repos/DefinitelyTyped/node_modules/nodegit/build/Release"
gyp
ERR! cwd $HOME/airlab/repos/DefinitelyTyped/node_modules/nodegit
gyp ERR! node -v v10.10.0
gyp
ERR! node-gyp -v v3.8.0
gyp ERR! not ok
[nodegit] ERROR - Could not finish install
[nodegit] ERROR - finished with error code: 1

@ghost
Copy link

ghost commented Sep 20, 2018

@ljharb That may be nodegit/nodegit#1490. You should be able to just ignore this and run npm run lint my-package-name directly, which doesn't use that dependency.

@jessetrinity jessetrinity merged commit 4022bfe into DefinitelyTyped:master Sep 21, 2018
@ljharb ljharb deleted the buffer_constructor branch September 22, 2018 00:02
@Flarna Flarna mentioned this pull request Nov 18, 2019
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Owner Approved A listed owner of this package signed off on the pull request. Popular package This PR affects a popular package (as counted by NPM download counts).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants