1

I have a monorepo with the following structure:

repo/
├─ node_modules/
├─ package.json
├─ packages/
│  ├─ design-system/
│  │  ├─ package.json // dependencies installed in repo/node_modules
├─ apps/
│  ├─ my-app/
│  │  ├─ node_modules/
│  │  ├─ package.json // dependencies installed in my-app/node_modules

repo/packages contains shared packages to be used by various apps in repo/apps. Shared packages have their dependencies in repo/node_modules, managed via Yarn Workspaces in the top level package.json:

"workspaces": [
  "packages/*"
]

repo/apps contains React Native apps. Apps in repo/apps have their own local node_modules and are NOT Yarn Workspaces (I decided against that because managing React Native dependencies with Yarn Workspaces was too cumbersome and flaky).

My current workflow is to run yarn install in the top level dir, then cd into repo/apps/my-app and run yarn install to install the local node_modules.

This has been working well, until now...

I have a design-system shared package with the following deps:

"devDependencies": {
  "@types/react": "17.0.2",
  "@types/react-native": "^0.67.1"
},
"peerDependencies": {
  "react": "17.0.2",
  "react-dom": "16.3.1",
  "react-native": "0.67.3"
}

my-app/package.json has many many dependencies, but I think the relevant one here is:

"devDependencies": {
  "@types/react-native": "^0.67.1"
}

(note how "@types/react": "17.0.2" is NOT a dependency of my-app. I have tried adding it, did not change anything).

When I import it in a component in my-app, I get the following error:

import { Button } from 'design-system'
import { View } from 'react-native'

const AppComponent = () => (
  <View> // error TS2786
    <Button/>
  </View>
)
TS2786: 'View' cannot be used as a JSX component.
   Its instance type 'View' is not a valid JSX element.
     The types returned by 'render()' are incompatible between these types.
       Type 'React.ReactNode' is not assignable to type 'import("/Users/sam/repo/node_modules/@types/react-native/node_modules/@types/react/index").ReactNode'.
         Type '{}' is not assignable to type 'ReactNode'.

What I understand from this error is that there is a conflict between the ReactNode type in the top level node_modules vs the one in the app node_modules.

My question is how and where do i fix this?

  • in repo/package.json?
  • in design-system/package.json?
  • in my-app/package.json?
  • in my-app/tsconfig.json?
  • somewhere else???
samzmann
  • 2,286
  • 3
  • 20
  • 47

1 Answers1

6

The answer was right here.

After inspecting my top level yarn.lock, I found that React 18 was indeed making its way into it.

"@types/react@*":
  version "18.0.9"

I had to add resolutions in the top level package.json:

// repo/package.json

"resolutions": {
  "@types/react": "17.0.2",
  "@types/react-dom": "17.0.2"
},

Which then changed the lock file to

"@types/react@*", "@types/react@17.0.2":
  version "17.0.2"

And the errors went away

samzmann
  • 2,286
  • 3
  • 20
  • 47
  • Is this still up to date ? Why would you want a typing version under the current version of react ? – Dimitri Kopriwa Dec 08 '22 at 10:28
  • @Dimitri, you should make sure that your `react` version and your `@types/react` version match, otherwise you get all type of strange problems. You can check it by running `yarn why @types/react` and `yarn why react` to see where are your versions coming from. It might be that an external library is adding an unwanted version – A. Llorente Dec 20 '22 at 07:21
  • The problem in my case was that two packages in my monorepo were using different versions of react (17 and 18). After I bumped up the 17 to 18 the errors went away – Ян Никодим Лудян Печул May 01 '23 at 23:32