Skip to content

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

Closed
@jeffora

Description

@jeffora

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions