Definitelytyped: @types/react-dom should not have dependency @types/node

Created on 7 Nov 2017  路  14Comments  路  Source: DefinitelyTyped/DefinitelyTyped

If you know how to fix the issue, make a pull request instead.

  • [x] I tried using the @types/react-dom package and had problems.
  • [x] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [x] I have a question that is inappropriate for StackOverflow. (Please ask any appropriate questions there).
  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @Asana @AssureSign @Microsoft

If you do not mention the authors the issue will be ignored.

@types/react-dom have a dependency @types/node, it will bring some problem.
Some types are different in NodeJS and browser, for example:

let timer: number = setTimeout(()=>{}, 100)

This should be compiled sucessfully, but get error Type 'Timer' is not assignable to type 'number'. if @types/node is exists.

Most helpful comment

Still have this problem, anyone have good way to resolve ?

All 14 comments

Currently we work around this issue by exhaustively specifying third-party libraries in tsconfig's compilerOptions.types - and we do not include node in that list. Are there any cleaner workarounds? This is unfortunately a common issue, as enzyme and typedoc are both offenders as well.

@abirmingham I do it with "postinstall": "rm -rf node_modules/@types/node"
Actually, many @types have this issue, want a better solution.
Also see this https://github.com/Microsoft/TypeScript/issues/18588

I ran into this, today.

Looking at the actual types, the only file needing node is https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-dom/server/index.d.ts

Can the server directory be moved out into a peer package? That file is only going to be included by a /// directive in the first place.

Still have this problem, anyone have good way to resolve ?

For setTimeout/setInterval specifically you can qualify it with window.setTimeout/window.setInterval to avoid the conflict for now.

My workaround, as we commit snapshots of the NPM packages to our application repo, has been to manually delete the dependency on the node package types, delete the references to node type definition files, delete the declarations for the functions that depend on node types, and also uninstall the node package. Obviously a temporary workaround, as an npm update will restore the node references which break compilation of our application.

Is it possible to fix this along the lines of @riggs's suggestion? Despite the name of the package, I'm only using these types on the client, not the server, so having separate packages for the client and server types would be ideal.

Can we create new package @types/react-dom-server which will have definition for react-dom/server and has dependency @types/node?

Yes, we need to install 2 dependency to get full typings for package react-dom and it will breaking change for some people who use react-dom/server.

Just a heads-up: I ran into another case of this today with @types/[email protected] and @types/[email protected]. Those libraries specify the @types/node dependencies, and also use a /// <reference types="node" /> declaration, which caused my workaround of exhaustively specifying types in tsconfig.json (without node typings) to fail.

@k8w starred that issue, thanks.

Is there any progress so far? It's totally unacceptable to reference server runtime definitions in a web browser environment. Using react-dom (and thus node) causes conflicts with any module loader that defines a require() method.

I am using renovate to automatically update my dependencies. It occurred that @types/node got an update as well as @types/react. Those updates cause conflicts if @types/react is referencing an older version:

On the right you can see the result after merging an update to @types/node while the left side contains the update to @types/react which references an older version. A workaround is to update them the other way round, but it is still irritating to see this happen at all.

This is actually a very serious issue as happened with vscode, it will pick up the node typings and thus provide misleading suggestions.

I'm surprised it still isn't resolved, but as tooling gets better the problem will only get worse.
So please move the server side rendering into its own package/make it opt in but in any case it shouldn't automatically include the node typings, if all you want is to use the React DOM api

I use yarn and my 3-step temporary solution that seems to work well so far is as follows:

  1. Create a .yarnclean file with the following content:
@types/node

This will make yarn delete the node_modules/@types/node directory after installing packages. After this step, @types/react-dom/server/index.d.ts will complain about being unable to find type definition for module "node" because of the triple slash reference /// <reference types="node" /> at the beginning. That's fixed by steps 2 and 3.

  1. Create a directory e.g. types in the project directory and make typescript treat it as a secondary @types directory by adding this to tsconfig.json:
{
  "compilerOptions": {   
    "baseUrl": "types",
    "typeRoots": ["types"],
  }
}
  1. Inside the types directory above, create a directory named node and inside that create a fake definition file index.d.ts:
export {}

Typescript will treat this file as the real @types/node type definition.

Either @types/react-dom or @types/node should separate the offending declarations to a separate package.

@types/react-dom can move their server functionality into a separate package such as @types/react-dom/server and make the main package free of NodeJS namespace. Or otherwise, @types/node can provide a separate package that contains all of its contents but the global.d.ts file. By doing so, package typings author can reference NodeJS only types by importing that package while not polluting the global scope. I suppose that in most cases, describing API function shape does not require NodeJS globals, like how react-dom only depends on NodeJS.ReadableStream. @types/node package can then merely combine this @types/node-builtin-modules and global.d.ts.

Although modifying @types/react-dom looks more "right", it seems that separating @types/node will have better net effect, as @types/node seems to be notorious for this globals polluting problem.

For setTimeout/setInterval specifically you can qualify it with window.setTimeout/window.setInterval to avoid the conflict for now.

There is no "window" variable in React Native. How would one go about solving this error in React Native?

Was this page helpful?
0 / 5 - 0 ratings