stitches icon indicating copy to clipboard operation
stitches copied to clipboard

TypeScript issue when exporting `styled` from a monorepo package

Open lucastobrazil opened this issue 2 years ago • 20 comments

Bug report

Describe the bug

I have a monorepo setup (see below for minimal repro) with the following structure:

monorepo/
-- packages
--- core
--- system

system is where we're exporting styled from stitches, however when using it in core

import { styled } from '@org/system'

const MyComponent = styled('div', {});
       ^^^^^^^^^^^

the below TypeScript error occurs.

The inferred type of 'MyComponent' cannot be named without a reference to 'system/node_modules/@stitches/react/types/config'. This is likely not portable. A type annotation is necessary.

We managed to eliminate this error by removing declaration: true from the tsconfig of core, however this prevented declaration files from getting created for our components which killed TS autocompletion (a big DX reason for using stitches).

Prior to moving the stitches stuff to system, it was in he core directory and worked fine.

To Reproduce

https://github.com/lucastobrazil/stitches-ts-repro

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Clone the repo and open with VSCode (Typescript enabled)
  2. npm install <-- we're using 4.4.2 to stay in line with stitches
  3. cd packages/system && npm install <-- install within this package too
  4. navigate to packages/core/index.ts and you will see the typescript error below

Expected behavior

We'd expect that the typings of the styled function are accessible and no error occurs, whilst still being able to output declaration files from core

Screenshots

Screen Shot 2022-07-05 at 11 53 50 pm

System information

  • OS: Mac OS
  • Version of Stitches: 1.2.8
  • VSCode Version: 1.68.1

lucastobrazil avatar Jul 05 '22 13:07 lucastobrazil

I wanted to take a look at this but couldn't reproduce the error of that example. I followed the steps @lucastobrazil provided above.

Here is my fork. Once I noticed the error wasn't there I added this line to check that TypeScript was working as intended.

image

It might be something on my side so it would be great if someone else could take a look at it as well.


System information

  • OS: Linux (WSL2)
  • Kernel: 5.10.16.3-microsoft-standard-WSL2 (x86_64)
  • VSCode version: 1.69.2

andresmarpz avatar Jul 31 '22 01:07 andresmarpz

@andresmarpz thanks for taking a look! try doing npm i in the system folder and the error should show up. Once stitches gets installed the TS error gets thrown. Not sure if this sheds any more light on the issue, but i guess once it's installed as a dependency TS tries to actually go in and infer the types.

lucastobrazil avatar Jul 31 '22 10:07 lucastobrazil

ps ill add that instruction to the reproduction steps

lucastobrazil avatar Jul 31 '22 10:07 lucastobrazil

Yep, you were right. I could get the reproduction working and tried a few things but couldn't find a workaround. Though, I don't know if it's really a Stitches problem, since I found #42873 and #29808 in TypeScript repository and reading a little through them it seems those are very related to your issue. Hope that might point you into something useful, but I'm not that knowledged to help you here :/

andresmarpz avatar Jul 31 '22 15:07 andresmarpz

I just ran into this and resolved it by coercing npm to install @stitches/react in the root node_modules folder rather than in a workspace node_modules. I'm not sure why it wasn't being hoisted to the root since it's only a dependent of that one package, but it resolved the issue for me.

jgoz avatar Aug 27 '22 18:08 jgoz

I faced the same issue with a pnpm monorepo. It seems to be directly related to this issue https://github.com/microsoft/TypeScript/issues/48212 and seems like it won't go away until it's fixed.

I ended with 3 possible workarounds

Option 1: Set paths

In your root tsconfig add @stitches/react to the paths

// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      // TODO: Remove the workaround whenever MS fixes the issue
      // https://github.com/microsoft/TypeScript/issues/48212
      "@stitches/react": ["./node_modules/@stitches/react"]
    }
  }
}

Option 2: Set baseUrl

I didnt try with other package manager, for a pnpm monorepo using workspace:* for local dependencies it worked fine

{
  "compilerOptions": {
    // TODO: Remove the workaround whenever MS fixes the issue
    // https://github.com/microsoft/TypeScript/issues/48212
    "baseUrl": "./node_modules"
  }
}

Option 3: Add an empty type import

Based on this comment https://github.com/microsoft/TypeScript/issues/48212#issuecomment-1204325586, in your component file add the following import

// TODO: Remove the workaround whenever MS fixes the issue
// https://github.com/microsoft/TypeScript/issues/48212
import type {} from '@stitches/react'

I hope it helps somehow :)

ivanbanov avatar Sep 12 '22 12:09 ivanbanov

@ivanbanov thank you so much! It worked! Can you please explain a bit more what is actually going on here? What is the root cause? Why these workarounds help?

Gorthog avatar Sep 13 '22 16:09 Gorthog

@ivanbanov for option 2, did you also put this in the root tsconfig.json? I'm still getting the same error with these solutions, so maybe I'm missing something. Do you have stitches installed at the root package.json too?

gregogun avatar Sep 22 '22 07:09 gregogun

I solved this problem installing the @stitches/react as dependency of the package that was having typing problems

drianoaz avatar Sep 29 '22 18:09 drianoaz

I solved this problem installing the @stitches/react as dependency of the package that was having typing problems

hmm tried this but still found some issues... are you able to share the repo at all? @drianoaz 🙏

gregogun avatar Nov 13 '22 16:11 gregogun

@gregogun I only have a tsconfig.json in the root

@Gorthog if I understood this comment correctly, TS resolves the transitive dependencies as "out of the project" and can not simply import it (I dont understand deeply to be honest). So, based on this transitive problem what I tried was to give a happy path to the compiler, so it does not get lost with such deps. Option 2 seems dangerous to be honest, but anyway it works 🤷

ivanbanov avatar Nov 14 '22 15:11 ivanbanov

hmm tried this but still found some issues... are you able to share the repo at all? @drianoaz 🙏

@gregogun the project where I made this fixes is private, but if you tell me which error exactly you are having, maybe I can help you

drianoaz avatar Nov 16 '22 18:11 drianoaz

thanks for the response @ivanbanov @drianoaz

manage to solve the issue with @ivanbanov second solution, turns out I had a missing ts dependency in my theme package.

it is working fine but I've noticed by doing this I lose the typed HTML attributes onClick, disabled etc. . Does anyone know a way to fix this? It will ofc work by extending React.ComponentProps<html element in here> but would really prefer not to do this 😅

gregogun avatar Nov 25 '22 16:11 gregogun

@gregogun I only have a tsconfig.json in the root

@Gorthog if I understood this comment correctly, TS resolves the transitive dependencies as "out of the project" and can not simply import it (I dont understand deeply to be honest). So, based on this transitive problem what I tried was to give a happy path to the compiler, so it does not get lost with such deps. Option 2 seems dangerous to be honest, but anyway it works 🤷

Thanks for that explanation!

I would like to add my 2 cents:

In my case I've found the problem is due to pnpm creating multiple copies of the same npm package across the monorepo. I changed all references of said package to peerDependencies except one that stayed under dependencies. Once that was done, there was only once copy of the npm package under node_modules and the error went away.

Gorthog avatar Dec 08 '22 07:12 Gorthog

I faced this issue in a monorepo containing the Design System using Stitches and its applications. I tried @ivanbanov workarounds, but none worked for me (still unsure why). Instead of trying a workaround or manually using type annotation on every usage of the styled function, I took a different approach. Here's how I fixed it:

  1. Install @stitches/react in both the design system package and the application.
  2. Create a shared Stitches configuration file in your design system package called stitches.shared.ts:
// stitches.shared.ts
import { createStitches } from '@stitches/react';
// Import your theme configuration here
import { themeConfig } from './path/to/your/themeConfig';

export const stitches = createStitches(themeConfig);

export const {
  styled,
  css,
  config,
  getCssText,
  globalCss,
  keyframes,
} = stitches;

Remember that you'll have to export this file, so update the bundling library you're using to have this file as an entry.

  1. Update the stitches.config.ts (or however you call it) file in your design system package to import and re-export the shared configuration:
import { stitches, styled, css, config, getCssText, globalCss, keyframes } from './stitches.shared';

export { styled, css, config, getCssText, globalCss, keyframes };

export type CSS = StitchesCSS<typeof config>;
  1. Create a stitches.config.ts file in your application:
import { StitchesCSS } from '@stitches/react';
import { stitches, styled, css, config, getCssText, globalCss, keyframes } from 'path/to/design-system-package/stitches.shared';

export { styled, css, config, getCssText, globalCss, keyframes };

export type CSS = StitchesCSS<typeof config>;

This configuration file imports the shared Stitches configuration from the design system package and re-exports it for use in the application. By doing this, we ensure the design system package and the Next.js application use the same Stitches configuration, fixing the type-related issues. This alternative solution should help resolve the error without using a workaround. 🙌🏻

jpedroschmitz avatar Apr 18 '23 00:04 jpedroschmitz

Hope this will help, following the steps above from everyone, I still wasn't able to stop the error from showing; So I started to play around with the tsconfig.json and found that setting the moduleResolution to something other then "bundler" solved my issue;

{
  "compilerOptions": {
    "moduleResolution": "node16",
  }
}

JackMostert avatar Aug 01 '23 21:08 JackMostert

I faced this issue in a dead simple library and it doesn't seem like any of the solutions mentioned here are helping. It looks like a Stitches issue for me now. Let me try to reproduce the problem in a repository.

OnkelTem avatar Dec 27 '23 18:12 OnkelTem

Here you are: https://github.com/OnkelTem/_stitches-inferred

  • No monorepo
  • Just a simple component
import { styled } from '@stitches/react';

export const Button = styled('button', {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
    padding: '10px 15px',
    '&:hover': {
        backgroundColor: 'lightgray',
    },
});

TS Error:

TS2742: The inferred type of Button cannot be named without a reference to
../node_modules/@stitches/react/types/css-util
. This is likely not portable. A type annotation is necessary.

OnkelTem avatar Dec 27 '23 21:12 OnkelTem

Opened a new report since it happens not only in a monorepo: https://github.com/stitchesjs/stitches/issues/1160

OnkelTem avatar Dec 27 '23 21:12 OnkelTem

It would be cool to at least update the tsconfig of this repo...

yovanoc avatar Apr 11 '24 19:04 yovanoc