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

Module resolution for sub-packages picks d.ts file when .ts file is available #20248

Closed
jeffora opened this issue Nov 24, 2017 · 3 comments
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@jeffora
Copy link

jeffora commented Nov 24, 2017

When importing a file from a subfolder, where that folder also contains a package.json file with a types or typings entry, the module resolver will select the declaration file pointed to by types, instead of following normal local directory resolution and selecting an index.ts file.

TypeScript Version: 2.7.0-dev.20171124 (also older versions)

Code

subPackage/package.json

{
  "name": "subpackage",
  "version": "0.0.1",
  "main": "./index.js",
  "types": "./index.d.ts"
}

subPackage/index.ts

export interface Utility {
  utilityFunction(): void;
}

export const utility: Utility = {
  utilityFunction: () => { console.log('utility function'); }
}

index.ts

import { utility } from './subPackage';

utility.utilityFunction();

$ tsc --declaration --traceresolution (this will work on the first run, and fail on the second)

======== Resolving module './subPackage' from 'package/index.ts'. ========
Explicitly specified module resolution kind: 'NodeJs'.
Loading module as file / folder, candidate module location 'package/subPackage', target file type 'TypeScript'.
File 'package/subPackage.ts' does not exist.
File 'package/subPackage.tsx' does not exist.
File 'package/subPackage.d.ts' does not exist.
Found 'package.json' at 'package/subPackage/package.json'.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field './index.d.ts' that references 'package/subPackage/index.d.ts'.
File 'package/subPackage/index.d.ts' exist - use it as a name resolution result.
======== Module name './subPackage' was successfully resolved to 'package/subPackage/index.d.ts'. ========
error TS5055: Cannot write file 'package/subPackage/index.d.ts' because it would overwrite input file.

Expected behavior:

When the import path is a local folder (i.e. starts with a ./), and is not a package from node_modules, I would expect normal file resolution rules to take priority to try to import an index.ts file.

Actual behavior:

When no d.ts file exists, the compilation (with --declaration) succeeds. When exactly the same command is run again, it fails, as it now resolves the imported file as index.d.ts, and also tries to generate that file. Typescript will error trying to overwrite a file that was also an input to compilation.

@jeffora
Copy link
Author

jeffora commented Nov 26, 2017

Thinking about this more I realise this is basically just mimicking the same behaviour as Node's module resolution, so I know it's not a simple issue or simple fix. However, it does seem problematic that the presence of a subpackage package.json with a types entry can cause different behaviour to exist between two subsequent calls to tsc --declaration.

@mhegazy
Copy link
Contributor

mhegazy commented Nov 27, 2017

Thinking about this more I realise this is basically just mimicking the same behaviour as Node's module resolution, so I know it's not a simple issue or simple fix.

That is what it is doing.. the compiler overlays TS-sepcific files on top of the node module resolution.

However, it does seem problematic that the presence of a subpackage package.json with a types entry can cause different behaviour to exist between two subsequent calls to tsc --declaration.

While i do agree in principal, i am not sure i see how it can be done otherwise. the process of resolving a module depends on finding a file in a set of prop-locations.. so if the file is not found it moves on to the next one..
the same happens for node "main" for instance, if that one was not found, it moves on to the next location, and looks for index.js for instance.

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Nov 27, 2017
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants