Definitelytyped: [@types/react-native]

Created on 2 Jun 2018  路  17Comments  路  Source: DefinitelyTyped/DefinitelyTyped

I just install the latest updates and I got a bunch of errors.

Using

  • "typescript": "^2.9.1"
  • "types/react-native": "^0.55.16",

cc: @VincentLanglet @alloy @tkrotoff

node_modules/@types/react-native/globals.d.ts:92:14 - error TS2300: Duplicate identifier 'RequestInfo'.

92 declare type RequestInfo = Request | string;
                ~~~~~~~~~~~


node_modules/@types/react-native/index.d.ts:8751:11 - error TS2451: Cannot redeclare block-scoped variable 'console'.

8751     const console: Console;
               ~~~~~~~


node_modules/@types/react-native/index.d.ts:8759:18 - error TS2717: Subsequent property declarations must have the same type.  Property 'geolocation' must be of type 'Geolocation', but here has type 'GeolocationStatic'.

8759         readonly geolocation: Geolocation;
                      ~~~~~~~~~~~


node_modules/@types/react-native/index.d.ts:8762:11 - error TS2451: Cannot redeclare block-scoped variable 'navigator'.

8762     const navigator: Navigator;
               ~~~~~~~~~


node_modules/typescript/lib/lib.dom.d.ts:15764:13 - error TS2451: Cannot redeclare block-scoped variable 'navigator'.

15764 declare var navigator: Navigator;
                  ~~~~~~~~~


node_modules/typescript/lib/lib.dom.d.ts:15940:13 - error TS2451: Cannot redeclare block-scoped variable 'console'.

15940 declare var console: Console;
                  ~~~~~~~


node_modules/typescript/lib/lib.dom.d.ts:15997:6 - error TS2300: Duplicate identifier 'RequestInfo'.

15997 type RequestInfo = Request | string;
           ~~~~~~~~~~~

Most helpful comment

Remove "dom" from "lib" in the tsconfig

All 17 comments

Remove "dom" from "lib" in the tsconfig

I'm hitting the same issue - how do I work around/apply a patch/get latest version with the fix?

@idvorkin tried what I did but I am not sure if that is the fixed now going back to this.

@yordis Thanks for the quick response - how did you work around? Happy to work through it in realtime on gitter

Running into the same issue on

@types/react-native: "0.55.18"

Expanding on what @yordis said about removing "dom" from the "lib" in "tsconfig", you may also see this issue if you DON'T SPECIFY the lib option in your tsconfig file (which happens to be the default for tsc --init). Notice that the lib option is NOT specified. It seems that the "dom" lib will be pulled in by default in this scenario?

BAD Config

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "jsx": "react",
     "sourceMap": true,
     "outDir": "./dist",
    "strict": true,
     "types": [
       "react",
       "react-native",
       "jest"
     ],
    "allowSyntheticDefaultImports": true,
  }
}

Here's a tsconfig that finally worked for me with TS 2.9.2 and @types/[email protected]. Notice that I've defined the "lib" option to ONLY pull in "es2015".
GOOD Config

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "lib": [
      "es2015",
    ],
    "jsx": "react",
     "sourceMap": true,
     "outDir": "./dist",
    "strict": true,
     "types": [
       "react",
       "react-native",
       "jest"
     ],
    "allowSyntheticDefaultImports": true,
  }
}

Overall, I'm not sure this counts as a "fix". There's a BUNCH of conflicts between @types/react-native, @types/node, and the dom. It seems like much of the core issue is platform-specific apis in the global scope (specifically different platforms that have very similar or identical apis). Most other projects (including ReactXP) opt to add the "skipLibCheck" option to tsconfig, although that doesn't feel like a real solution either. Would love to see a place where some of the core minds from the typescript team discussed this issue (I don't think it's specific to react-native).

@lukewis If I remove dom from lib like you, I get the FormData error:

TS2693: 'FormData' only refers to a type, but is being used as a value here.

@ATShiTou hmm... I'm not using that type so I'm not certain. I would expect @types/react-native to provide that definition. Have any sample code you can share?

I've hust installed create-react-native-typescript-app and created a project. Compiling of this project gives errors described here. Adding skipLibCheck to tsconfig does not help.

LOL, I've added "lib": [] to tsconfig and it still givess errors, but "lib": ["es2015"] helps. Thanks. :-)

Any suggestions for people that have scenarios where the code base runs in the browser (e.g. using react-native-web) and we need to unify the differences between the lib.dom typings and the react-native typings. The only option I have that currently works is to patch the react-native typings in situ using patch-package, removing the definitions in the typing that are already declared in lib.dom.

@RyanThomas73 I've spent several hours pondering that same question and I've not come to any good solutions. Here are a few that I've pondered:

  1. react-native-web becomes responsible for maintaining their OWN type definitions (and ensuring they don't collide with the dom types).
    1.1 This seems like the most "philosophically" correct solution. However, this sucks because the whole point to react-native-web is to provide an api-compatible implementation for web. It's it's "api-compatible" then why create duplicate type definitions? Let's keep it DRY, right?
  2. react-native modifies their type definitions to not collide with dom types
    2.1 This doesn't seem viable, because react-native knows nothing of the dom or react-native-web. Why should it care? It doesn't seem like their problem.

I think number 1 is the "most correct" option, but it would place a pretty significant burden on the react-native-web "team" to try to keep their type definitions in sync with the react native ones. Aside from that, it seems like what you're currently doing is the next best thing :/ Still hoping that someone more knowledgeable than me will propose something better! I've also seen this same problem arise when someone creates an "api-compatible" implementation of a NodeJS api (example: someone implements an "fs" replacement that uses the browser's local storage).....we don't want to include ALL of @types/node, but it sure sucks to have to fork all the "fs" definitions!

@lukewis Thanks for weighing in! It's definitely a tricky problem. Option 1 is bad because of the maintenance and duplicate definitions. Patching in situ isn't great either because it requires new patch file(s) be created any time the consumer wants/needs to upgrade versions.

Both options have the considerable drawback of ignoring the underlying problem of the signature differences in the platform implementations. If I accidentally use one of the global signatures that's only valid in the browser my code will blow up when running on android/ios.

I was hoping their might be a slightly better middle ground solution that cuts down on the maintenance work and provides some type safety against the signature differences, but I have no idea what that solution might be. For a true solution, I think one of the below will have to be achieved:

  • The typescript compiler and related tools for the build step are being called individually per platform that is being built and the typings are selected contextually based on platform. OR

  • The globals that the react-native ecosystem defines are maintained in a way where their usage signatures match the usage signatures of globals in other ecosystems (e.g. node, dom).

@RyanThomas73 Your first bullet point is interesting. It feels very similar to the issues that the DotNet team is trying to solve with things like "multi-targeting" and DotNetStandard. However, in that world, the compiler team (Xamarin/DotNetCore/DotNetStandard) is responsible for all the platform-specific definitions (which doesn't feel feasible here). The problem is also further compounded by type definition packages that depend on "platform" definitions (like @types/node or @types/react-native). There are some packages originally designed to run on NodeJS that run perfectly fine on react-native, but it's difficult to use them due to type definition conflicts.

As you say, I think this is a "platform" level issue (not specific to react-native). I've tried a few times to catch the ear of someone from the typescript team to start a discussion on this topic, but thus far have been unsucessful (or looking in the wrong places if this discussion is already happening).

  1. Remove "dom" from "lib" in the tsconfig.json
  2. config the web specific dir in tsconfig.json "exclude" option

it works for me

Remove "dom" from "lib" in the tsconfig

@yordis my hero!

I have a similar use case as @RyanThomas73 where we need both types, lib.dom and react-native types but it gives the "Duplicate identifier..." errors. As a temporary workaround, I've added skipLibCheck: true in tsconfig but it's not ideal, I'm curious to know if anyone has been in the same situation and how are they managing it...

Was this page helpful?
0 / 5 - 0 ratings