Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility issue between dts output method and yarn's strict dependency resolution approach #53580

Closed
flex-jonghyen opened this issue Mar 30, 2023 · 12 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@flex-jonghyen
Copy link

flex-jonghyen commented Mar 30, 2023

Bug Report

🔎 Search Terms

yarn, yarn berry, pnp, interface, dependency hoisting, module resolve

and... yarnpkg/berry#5287

🕗 Version & Regression Information

System:
    OS: macOS 13.2.1
    CPU: (10) arm64 Apple M1 Max
  Binaries:
    Node: 16.18.0 - /private/var/folders/ld/_l4gwlwn2j1fxtlp_mpc5xr00000gn/T/xfs-e9ba9998/node
    Yarn: 3.2.3 - /private/var/folders/ld/_l4gwlwn2j1fxtlp_mpc5xr00000gn/T/xfs-e9ba9998/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v16.18.0/bin/npm

and typescript 5.0.0


I've been experiencing a compatibility issue between the output method of TypeScript's  .dts  files and yarn's strict dependency resolution approach, which has led to dependency problems in my project.

I would like to provide more details about this issue:

I'm in the following situation: I have 3 packages, A, B, and C, with dependencies in the order of A -> B -> C.

Package A exports the following code (this is part of the actual code):

export interface ThemedStyled<Theme, ...> {...};
export const createThemedStyled<Theme>(theme: Theme): ThemedStyled<Theme, ...>;

Package B uses createThemedStyled from package A:

import { createThemedStyled } from 'A';
export const { styled } = createThemedStyled(myTheme);

Finally, package C uses styled from package B:

export const Button = styled(`...style code`);

After building each package and generating their dts, the output for package C's dts looks like this:

export declare const Button: import('A').ThemedStyled<Theme, ...>;

However, it seems that in pnp, if package C doesn't explicitly have package A as a dependency, A cannot be resolved. This works correctly with nodeLinker: node-modules.

And I don't think this issue is tied to a specific library or the TypeScript compiler.
This issue seems to occur only in the dts, and adding package A to the devDependencies of the problematic package C resolves the issue.

The log is part of result of tsc --traceResolution about C package.

======== Resolving module '@stitches/react/types/styled-component' from '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/components/input/styled.d.ts'. ========
Explicitly specified module resolution kind: 'NodeNext'.
Resolving in CJS mode with conditions 'node', 'require', 'types'.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/components/input/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/components/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/package.json' exists according to earlier cached lookups.
Loading module '@stitches/react/types/styled-component' from 'node_modules' folder, target file type 'TypeScript'.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/components/input/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/components/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/dist/package.json' does not exist according to earlier cached lookups.
File '/Users/grapgrap/workspace/flex-frontend/.yarn/__virtual__/@flexteam-linear-virtual-f4877fba30/1/packages/linear/package.json' exists according to earlier cached lookups.
Loading module '@stitches/react/types/styled-component' from 'node_modules' folder, target file type 'JavaScript'.
======== Module name '@stitches/react/types/styled-component' was not resolved. ========

⏯ Playground Link

💻 Code

reproducing repo: https://github.com/flex-jonghyen/pnp-reproduce

🙁 Actual behavior

The problem is importing dependencies of dependencies in  .dts  files that are unknown to the consumer.

🙂 Expected behavior

The problem does not occur.

@flex-jonghyen
Copy link
Author

If this issue cannot be resolved in both yarn and TypeScript, I would appreciate it if you could let me know how I can work around the problem.

@jakebailey
Copy link
Member

Given that C lists an import for A, a fix would be to declare that C depends on A so the import resolves. If the package is out of your control, you could use: https://yarnpkg.com/configuration/yarnrc#packageExtensions

If you explicitly annotate the type, you may also be able to avoid this generated node.

@flex-jonghyen
Copy link
Author

flex-jonghyen commented Mar 30, 2023

Thanks for your fast response! I needed a solution from the TypeScript side.

If you explicitly annotate the type, you may also be able to avoid this generated node.

I might not have understood this correctly. If we explicitly provide A's type from B to C, will it resolve the issue?

import { createThemedStyled, type ThemedStyled } from 'A';

export interface MyThemedStyled extends ThemedStyled<typeof myTheme, ... > {};
export const themedStyled: MyThemedStyled = createThemedStyled(myTheme);

And while reproducing the issue, I found out that this problem only occurs with interfaces, not with types.

Is there any documentation that explains why types aren't imported using the import function?

@jakebailey
Copy link
Member

Probably, via the explicit annotation.

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Mar 30, 2023
@RyanCavanaugh
Copy link
Member

The declaration emitter will always (if it can) use an explicit type annotation based on the one you wrote, so that solution is definitely available. If it can't do that, it has to synthesize some name for that type, and it's possible (indeed likely) that the only way to refer to the type is through an import(" type.

@fatcerberus
Copy link

it's possible (indeed likely) that the only way to refer to the type is through an import(" type.

…which IIRC is caught by, e.g. isolatedModules

@RyanCavanaugh
Copy link
Member

…which IIRC is caught by, e.g. isolatedModules

AFAIK isolatedModules only controls which kinds of TS-specific constructs (namespace, enum) can appear in .ts files and has no effect on .d.ts emit. See also paragraph 3 here

@fatcerberus
Copy link

Hmm, then what's the deal with the error that goes something like "type T cannot be named without reference to module 'foo'" that only shows up when declarations are enabled? Am I misunderstanding the purpose of that error?

@RyanCavanaugh
Copy link
Member

That error appears when the specifier of the module appears non-portable, e.g. would be something like ../../../other/project where ../../.. escapes out of the root dir of the project

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow or the TypeScript Discord community.

@flex-jonghyen
Copy link
Author

I think this problem maybe resolve by #58176

@jakebailey
Copy link
Member

Potentially, do try the next nightly and report back!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants