Skip to content

With project references, some cross-package imports of inferred types are emitted with relative paths #39117

Closed
@ecraig12345

Description

@ecraig12345

TypeScript Version: 3.9.5 (also repros with nightly)

Search Terms: project references, declaration files, tsconfig paths, inferred types

Code

The repro requires a monorepo with project references plus paths in the tsconfig. Full repro with the problematic compiled output checked in here: https://github.com/ecraig12345/learn-a/tree/inferred-relative-imports (it's fairly minimal but may still include a few settings which turn out to be tangential to the issue, sorry)

Here's a summary...

@fluentui/pkg2 depends on @fluentui/pkg1, and both live in the same monorepo under a packages folder.

pkg2's tsconfig has a project reference pointing to pkg1, and both build with composite: true.

They inherit from a shared tsconfig which has a path config like this (to allow imports directly from the root of each package):

"baseUrl": ".",
"paths": {
  "@fluentui/*": ["packages/*/src"]
}

The problem comes when you have a file in one package (pkg2/src/index.ts in the repro) which has an implicit/inferred reference to a type from another local project-referenced package.

import { IThings } from '@fluentui/pkg1';

export function fn4() { // inferred return type: IThings from pkg1
  const a: IThings = { thing1: { a: 'b' } };
  return a.thing1;
}

This inferred type need not be stated locally, but it will show up in the declaration file as an inline import().

Expected behavior:

Compile each package with tsc (or in the repro, run yarn build from the root).

pkg2's index.d.ts looks like this:

export declare function fn4(): import("@fluentui/pkg1").IThing;

Actual behavior:

pkg2's index.d.ts looks like this, which will break consumers:

export declare function fn4(): import("../../pkg1/src").IThing;

pkg2/src/index.ts output also adds an src folder under lib, which I wouldn't expect (pkg2/lib/src/index.{js,d.ts}), but this is probably unrelated.

Variants:

  • Same behavior if -b is added to the build command.
  • Same behavior if using rootDir instead of include, just different output directory structure.
  • Same behavior if the config inheritance is removed and paths config is moved to each project.
  • Without project references, you end up with a directory structure like this, which I also don't understand, but is not the same issue:
pkg2/
  lib/
    pkg1/src/<files>
    pkg2/src/<files>

Playground Link: can't be shown on playground

Related Issues: didn't see anything else quite like this

Metadata

Metadata

Assignees

Labels

Fix AvailableA PR has been opened for this issueNeeds InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions