microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.08k stars 12.29k forks source link

"The inferred type of X cannot be named without a reference to Y" (TS2742) still happens, when working with npm link to link packages manually #58914

Open Teascade opened 2 weeks ago

Teascade commented 2 weeks ago

šŸ”Ž Search Terms

is:issue is:open 2742

šŸ•— Version & Regression Information

This seems to not be a regression bug

āÆ Playground Link

https://github.com/Teascade/typescript-error-demonstration

šŸ’» Code

// In the example provided
// https://github.com/Teascade/typescript-error-demonstration

import { extended } from '@privateprefix/lib';

// src/index.ts(4,14): error TS2742: The inferred type of 'a' cannot be named without a reference to '@privateprefix/lib/node_modules/joi'. This is likely not portable. A type annotation is necessary.
export const a = extended.object().keys();

Replacing this with

// Joi is declared, but never used ts(6133)
import { type Joi, extended } from '@privateprefix/lib';

// This works now, though
export const a = extended.object().keys();

šŸ™ Actual behavior

Produces src/index.ts(4,14): error TS2742: The inferred type of 'a' cannot be named without a reference to '@privateprefix/lib/node_modules/joi'. This is likely not portable. A type annotation is necessary.

šŸ™‚ Expected behavior

No error is to be expected

Additional information about the issue

In https://github.com/microsoft/TypeScript/issues/42873#issuecomment-2066874644 it was mentioned, that this issue would now be resolved in TypeScript beta 5.5.0, but it seems to still be broken in this specific scenario

I've made a minimal repository to reroduce this issue in https://github.com/Teascade/typescript-error-demonstration

The GitHub repository has a github action in which the issue is reproduced: https://github.com/Teascade/typescript-error-demonstration/actions/runs/9568149578/job/26377636108

Teascade commented 2 weeks ago

I did not go into vivid detail into what could possibly be causing this issue, when it has supposedly been fixed in the general case for pnpm, because I frankly do not know what it could be, but the repository is not very big and contains everything needed to reproduce the error.

I'm suspecting this instance has something to do with npm link, as when the library is simply installed via tarball, it works just fine

weswigham commented 2 weeks ago

It doesn't really have anything to do with npm link - it's just that we don't see the Joi types reexported in @privateprefix/lib as an autogeneratable way to reference joi's innards, hence why it works when you explicitly import the alias to Joi. (The tarball install works because npm hoists the install to the top level, rather than doing the strict dependency nesting the link does.) We do do a little bit of looking for reexports, but generally we look for complete reexports, where one module is another module via export = - a nested reexport like this, where you import a default and reexport it as a named member I just don't think is an alias we current traverse through while looking for reachable ways to name the module. So this is probably fixable, but the logic's going to be a bit weird, since we'll be looking for module symbol aliases at... basically every symbol name everywhere (rather than just reachable filenames).

Teascade commented 2 weeks ago

Thanks for the answer @weswigham, as an aspiring Compiler Technician myself I actually entirely understand, and was honestly a little surprised as a similar problem causing this error had been solved via #42873, so it gave me hope that maybe this could be solved too, somehow.

This problem occurs to me at work, and while I obviously can't disclose the details, the situation (and the problem) is pretty much identical. The part that frustrates me the most, is that we used to only use Javascript + JSDoc and simply TypeScript-checked all of our files. Now that we are transitioning to full-typescript, this has become an issue, almost out of nowhere. It's befuddling, and frustrating.

I must try and check, if the problem persists in the minimal repository if the files were instead JS+JSDoc+autogenerated Typescript Declaration files, but I suspect the problem would not exist there.

This is especially frustrating again, because we have a lot of repositories, and using them via published npm-packages works just fine (ie. the tarball works), but manually linking the packages together during development, to make development easier, now breaks :/

samhh commented 1 week ago

I'm seeing a similar issue in a monorepo on 5.5 ("moduleResolution": "Node16") where a package re-exports io-ts.

error TS2742: The inferred type of 'Foo' cannot be named without a reference to '../../../node_modules/monorepo-package/transient-module.js'. This is likely not portable. A type annotation is necessary.

export const Foo = t.etc({
             ~~~

The module from which we import * as t itself imports a type from transient-module. I can workaround this with import "monorepo-package/transient-module" alongside Foo, but that's far from ideal.

If this isn't expected or it's unclear why it'd be happening I can try and come up with a small repro.