-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Introduce strictCustomConditions
option for custom exports
/ imports
conditions with no fallback to other conditions if the file does not exist
#61363
Comments
On a completely unrelated side note, I would like to ask the TypeScript team to have a look at #61256 (comment). The issue was closed too quickly for me to write an answer, and now I think no one is going to see it unless I mention the issue again. I am convinced it should be reopened, and the comment explains why in great detail. |
This could be seen as a duplicate of #50762 |
@Andarist it is closely related for sure. What is the current status of that issue? I see it mentioned as a deprecation candidate for TypeScript 6.0 in #54500, which is not too bad considering the version will probably be released this year already. To help solve the issue with monorepos, I would suggest not only deprecating the fallback mechanism, but also introducing a boolean option to completely disable it. The option could be named One issue with it is that it could only be used if all the third-party dependencies of my package have already structured their |
Since it turns out the fallback mechanism is actually a bug rather than a feature, here are two alternative suggestions:
|
π Search Terms
custom conditions, package.json exports / imports, customConditions, TSConfig
β Viability Checklist
β Suggestion
TypeScript does not report an error if a custom condition specified in
customConditions
is encountered, but the file it resolves to does not exist. Instead, it keeps trying to resolve the requested module using other conditions such astypes
ordefault
(β Demo).By contrast, Node.js stops trying as soon as the first relevant condition is encountered and throws a runtime error if the file it resolves to does not exist (β Demo).
The motivation behind this fallback mechanism of TypeScript is probably to avoid problems in cases where my package happens to use the same custom condition name as one of its third-party dependencies. For example, both my package and its dependency could use the
source
condition to resolve to the source.ts
files, but since those are normally not published, trying to import from this dependency would result in an error if the fallback mechanism were not in place.If my idea is right and this is indeed the motivation for the behavior, well, I am not very convinced. I think there is only one right solution to problems that could arise due to using the same custom condition names as third-party dependencies, and that is to make sure you don't! One common pattern to avoid such conflicts are scoped condition names suggested by @colinhacks, the creator of Zod, in Live types in a TypeScript monorepo.
So as not to introduce a breaking change to the behavior of
customConditions
, I suggest introducing a new TSConfig option for specifying custom conditions for which the fallback mechanism would not be used. I thinkstrictCustomConditions
would be a good name for it.I still haven't explained how it could be useful though, and that's what I am going to do now.
π Motivating Example
What motivated me to post this feature request was the realization there was no good way to use project references in monorepos employing workspaces I came to during a discussion I started with this comment in #40431.
The issue is shown very well in this demo I adapted from one @robbiespeed posted in that thread. There,
@ts-ref/source
custom conditions are used for source.ts
files. If you runpnpm build
, then renamepackages/a/foo.ts
, and then runpnpm build
again, you will not see an error despite thefoo.ts
file that we mean to import frombar.ts
no longer being available.In general, if you delete, move or rename a source
.ts
file that has already been compiled with"declaration": true
(which is how all referenced projects are compiled because they are required to be composite), TypeScript will not report an error when trying to import from it unless you also manually delete the corresponding declaration file. The reason is exactly the fallback mechanism: instead of stopping and reporting an error when the source file doesn't exist, TypeScript continues to inspect the remainingexports
conditions and ends up resolving with thetypes
condition that provides the declaration file.This behavior can cause developers a lot of confusion, e.g. because imports from files that shouldn't exist anymore are suggested in the editor. There have been a couple other proposals that could solve the Issue:
.tsbuildinfo
files, see my comment)tsc --build --noEmit
Β #53979However, it doesn't look like either of these ideas is going to be implemented any time soon, which is exactly why I am opening this issue so as to propose an alternative solution and hopefully have more luck with it :)
π» Use Cases
β For βlive typesβ in monorepos based on workspaces.
β The shortcomings of
customConditions
are described above.β Not using workspaces whenever possible, otherwise using Google's Wireit tool to automatically delete declaration files for which the corresponding source files no longer exist (see comment).
The text was updated successfully, but these errors were encountered: