Follow and respect export maps when generating module specifiers (#46159)

* Follow and respect export maps when generating module specifiers

* Type baseline updates from master merge
This commit is contained in:
Wesley Wigham 2021-10-01 13:54:07 -07:00 committed by GitHub
parent 9ed49b6ba7
commit a02a7ab8e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1695 additions and 11 deletions

View File

@ -1708,7 +1708,8 @@ namespace ts {
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
}
function allKeysStartWithDot(obj: MapLike<unknown>) {
/* @internal */
export function allKeysStartWithDot(obj: MapLike<unknown>) {
return every(getOwnKeys(obj), k => startsWith(k, "."));
}
@ -1922,14 +1923,15 @@ namespace ts {
}
return toSearchResult(/*value*/ undefined);
}
}
function isApplicableVersionedTypesKey(conditions: string[], key: string) {
if (conditions.indexOf("types") === -1) return false; // only apply versioned types conditions if the types condition is applied
if (!startsWith(key, "types@")) return false;
const range = VersionRange.tryParse(key.substring("types@".length));
if (!range) return false;
return range.test(version);
}
/* @internal */
export function isApplicableVersionedTypesKey(conditions: string[], key: string) {
if (conditions.indexOf("types") === -1) return false; // only apply versioned types conditions if the types condition is applied
if (!startsWith(key, "types@")) return false;
const range = VersionRange.tryParse(key.substring("types@".length));
if (!range) return false;
return range.test(version);
}
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {

View File

@ -555,6 +555,77 @@ namespace ts.moduleSpecifiers {
}
}
const enum MatchingMode {
Exact,
Directory,
Pattern
}
function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode = MatchingMode.Exact): { moduleFileToTry: string } | undefined {
if (typeof exports === "string") {
const pathOrPattern = getNormalizedAbsolutePath(combinePaths(packageDirectory, exports), /*currentDirectory*/ undefined);
const extensionSwappedTarget = hasTSFileExtension(targetFilePath) ? removeFileExtension(targetFilePath) + tryGetJSExtensionForFile(targetFilePath, options) : undefined;
switch (mode) {
case MatchingMode.Exact:
if (comparePaths(targetFilePath, pathOrPattern) === Comparison.EqualTo || (extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern) === Comparison.EqualTo)) {
return { moduleFileToTry: packageName };
}
break;
case MatchingMode.Directory:
if (containsPath(pathOrPattern, targetFilePath)) {
const fragment = getRelativePathFromDirectory(pathOrPattern, targetFilePath, /*ignoreCase*/ false);
return { moduleFileToTry: getNormalizedAbsolutePath(combinePaths(combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) };
}
break;
case MatchingMode.Pattern:
const starPos = pathOrPattern.indexOf("*");
const leadingSlice = pathOrPattern.slice(0, starPos);
const trailingSlice = pathOrPattern.slice(starPos + 1);
if (startsWith(targetFilePath, leadingSlice) && endsWith(targetFilePath, trailingSlice)) {
const starReplacement = targetFilePath.slice(leadingSlice.length, targetFilePath.length - trailingSlice.length);
return { moduleFileToTry: packageName.replace("*", starReplacement) };
}
if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice) && endsWith(extensionSwappedTarget, trailingSlice)) {
const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length);
return { moduleFileToTry: packageName.replace("*", starReplacement) };
}
break;
}
}
else if (Array.isArray(exports)) {
return forEach(exports, e => tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, e, conditions));
}
else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null
if (allKeysStartWithDot(exports as MapLike<unknown>)) {
// sub-mappings
// 3 cases:
// * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode))
// * pattern mappings (contains a *)
// * exact mappings (no *, does not end with /)
return forEach(getOwnKeys(exports as MapLike<unknown>), k => {
const subPackageName = getNormalizedAbsolutePath(combinePaths(packageName, k), /*currentDirectory*/ undefined);
const mode = endsWith(k, "/") ? MatchingMode.Directory
: stringContains(k, "*") ? MatchingMode.Pattern
: MatchingMode.Exact;
return tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, subPackageName, (exports as MapLike<unknown>)[k], conditions, mode);
});
}
else {
// conditional mapping
for (const key of getOwnKeys(exports as MapLike<unknown>)) {
if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) {
const subTarget = (exports as MapLike<unknown>)[key];
const result = tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, subTarget, conditions);
if (result) {
return result;
}
}
}
}
}
return undefined;
}
function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: CompilerOptions): string | undefined {
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
if (normalizedTargetPath === undefined) {
@ -586,7 +657,15 @@ namespace ts.moduleSpecifiers {
let moduleFileNameForExtensionless: string | undefined;
while (true) {
// If the module could be imported by a directory name, use that directory's name
const { moduleFileToTry, packageRootPath } = tryDirectoryWithPackageJson(packageRootIndex);
const { moduleFileToTry, packageRootPath, blockedByExports, verbatimFromExports } = tryDirectoryWithPackageJson(packageRootIndex);
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Classic) {
if (blockedByExports) {
return undefined; // File is under this package.json, but is not publicly exported - there's no way to name it via `node_modules` resolution
}
if (verbatimFromExports) {
return moduleFileToTry;
}
}
if (packageRootPath) {
moduleSpecifier = packageRootPath;
isPackageRootPath = true;
@ -621,12 +700,21 @@ namespace ts.moduleSpecifiers {
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Classic && packageName === nodeModulesDirectoryName ? undefined : packageName;
function tryDirectoryWithPackageJson(packageRootIndex: number) {
function tryDirectoryWithPackageJson(packageRootIndex: number): { moduleFileToTry: string, packageRootPath?: string, blockedByExports?: true, verbatimFromExports?: true } {
const packageRootPath = path.substring(0, packageRootIndex);
const packageJsonPath = combinePaths(packageRootPath, "package.json");
let moduleFileToTry = path;
if (host.fileExists(packageJsonPath)) {
const packageJsonContent = JSON.parse(host.readFile!(packageJsonPath)!);
// TODO: Inject `require` or `import` condition based on the intended import mode
const fromExports = packageJsonContent.exports && typeof packageJsonContent.name === "string" ? tryGetModuleNameFromExports(options, path, packageRootPath, packageJsonContent.name, packageJsonContent.exports, ["node", "types"]) : undefined;
if (fromExports) {
const withJsExtension = !hasTSFileExtension(fromExports.moduleFileToTry) ? fromExports : { moduleFileToTry: removeFileExtension(fromExports.moduleFileToTry) + tryGetJSExtensionForFile(fromExports.moduleFileToTry, options) };
return { ...withJsExtension, verbatimFromExports: true };
}
if (packageJsonContent.exports) {
return { moduleFileToTry: path, blockedByExports: true };
}
const versionPaths = packageJsonContent.typesVersions
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
: undefined;
@ -641,7 +729,6 @@ namespace ts.moduleSpecifiers {
moduleFileToTry = combinePaths(packageRootPath, fromPaths);
}
}
// If the file is the main module, it can be imported by the package name
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
if (isString(mainFileRelative)) {

View File

@ -88,4 +88,101 @@ namespace ts {
commandLineArgs: ["-b", "/src", "--verbose"]
});
});
// https://github.com/microsoft/TypeScript/issues/44434 but with `module: node12`, some `exports` maps blocking direct access, and no `baseUrl`
describe("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers across referenced projects resolve correctly", () => {
verifyTsc({
scenario: "moduleSpecifiers",
subScenario: `synthesized module specifiers across projects resolve correctly`,
fs: () => loadProjectFromFiles({
"/src/src-types/index.ts": Utils.dedent`
export * from './dogconfig.js';`,
"/src/src-types/dogconfig.ts": Utils.dedent`
export interface DogConfig {
name: string;
}`,
"/src/src-dogs/index.ts": Utils.dedent`
export * from 'src-types';
export * from './lassie/lassiedog.js';
`,
"/src/src-dogs/dogconfig.ts": Utils.dedent`
import { DogConfig } from 'src-types';
export const DOG_CONFIG: DogConfig = {
name: 'Default dog',
};
`,
"/src/src-dogs/dog.ts": Utils.dedent`
import { DogConfig } from 'src-types';
import { DOG_CONFIG } from './dogconfig.js';
export abstract class Dog {
public static getCapabilities(): DogConfig {
return DOG_CONFIG;
}
}
`,
"/src/src-dogs/lassie/lassiedog.ts": Utils.dedent`
import { Dog } from '../dog.js';
import { LASSIE_CONFIG } from './lassieconfig.js';
export class LassieDog extends Dog {
protected static getDogConfig = () => LASSIE_CONFIG;
}
`,
"/src/src-dogs/lassie/lassieconfig.ts": Utils.dedent`
import { DogConfig } from 'src-types';
export const LASSIE_CONFIG: DogConfig = { name: 'Lassie' };
`,
"/src/tsconfig-base.json": Utils.dedent`
{
"compilerOptions": {
"declaration": true,
"module": "node12"
}
}`,
"/src/src-types/package.json": Utils.dedent`
{
"type": "module",
"exports": "./index.js"
}`,
"/src/src-dogs/package.json": Utils.dedent`
{
"type": "module",
"exports": "./index.js"
}`,
"/src/src-types/tsconfig.json": Utils.dedent`
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"composite": true
},
"include": [
"**/*"
]
}`,
"/src/src-dogs/tsconfig.json": Utils.dedent`
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../src-types" }
],
"include": [
"**/*"
]
}`,
}, ""),
modifyFs: fs => {
fs.writeFileSync("/lib/lib.es2020.full.d.ts", tscWatch.libFile.content);
fs.symlinkSync("/src", "/src/src-types/node_modules");
fs.symlinkSync("/src", "/src/src-dogs/node_modules");
},
commandLineArgs: ["-b", "src/src-types", "src/src-dogs", "--verbose"]
});
});
}

View File

@ -0,0 +1,36 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
tests/cases/conformance/node/index.ts(3,14): error TS2742: The inferred type of 'a' cannot be named without a reference to './node_modules/inner/other.js'. This is likely not portable. A type annotation is necessary.
tests/cases/conformance/node/index.ts(3,19): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/index.ts (3 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner")).x();
~
!!! error TS2742: The inferred type of 'a' cannot be named without a reference to './node_modules/inner/other.js'. This is likely not portable. A type annotation is necessary.
~~~~~
!!! error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": "./index.js"
}

View File

@ -0,0 +1,30 @@
//// [tests/cases/conformance/node/nodeModulesExportsBlocksSpecifierResolution.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [index.js]
export const a = (await import("inner")).x();

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner" : "inner"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,33 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
tests/cases/conformance/node/index.ts(3,14): error TS2742: The inferred type of 'a' cannot be named without a reference to './node_modules/inner/other.js'. This is likely not portable. A type annotation is necessary.
==== tests/cases/conformance/node/index.ts (2 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner")).x();
~
!!! error TS2742: The inferred type of 'a' cannot be named without a reference to './node_modules/inner/other.js'. This is likely not portable. A type annotation is necessary.
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": "./index.js"
}

View File

@ -0,0 +1,30 @@
//// [tests/cases/conformance/node/nodeModulesExportsBlocksSpecifierResolution.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [index.js]
export const a = (await import("inner")).x();

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner" : "inner"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,40 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other.js' or its corresponding type declarations.
tests/cases/conformance/node/index.ts(3,19): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/index.ts (2 errors) ====
// esm format file
import { Thing } from "inner/other.js"; // should fail
~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other.js' or its corresponding type declarations.
export const a = (await import("inner")).x();
~~~~~
!!! error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
".": {
"default": "./index.js"
},
"./other": {
"default": "./other.js"
}
}
}

View File

@ -0,0 +1,41 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationConditions.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other.js"; // should fail
export const a = (await import("inner")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
".": {
"default": "./index.js"
},
"./other": {
"default": "./other.js"
}
}
}
//// [index.js]
export const a = (await import("inner")).x();
//// [index.d.ts]
export declare const a: import("inner/other").Thing;

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other.js"; // should fail
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other.js"; // should fail
>Thing : any
export const a = (await import("inner")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner" : "inner"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,37 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other.js' or its corresponding type declarations.
==== tests/cases/conformance/node/index.ts (1 errors) ====
// esm format file
import { Thing } from "inner/other.js"; // should fail
~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other.js' or its corresponding type declarations.
export const a = (await import("inner")).x();
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
".": {
"default": "./index.js"
},
"./other": {
"default": "./other.js"
}
}
}

View File

@ -0,0 +1,41 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationConditions.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other.js"; // should fail
export const a = (await import("inner")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
".": {
"default": "./index.js"
},
"./other": {
"default": "./other.js"
}
}
}
//// [index.js]
export const a = (await import("inner")).x();
//// [index.d.ts]
export declare const a: import("inner/other").Thing;

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other.js"; // should fail
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other.js"; // should fail
>Thing : any
export const a = (await import("inner")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner" : "inner"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,35 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
tests/cases/conformance/node/index.ts(3,19): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/index.ts (2 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner/index.js")).x();
~~~~~
!!! error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./": "./"
}
}

View File

@ -0,0 +1,36 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationDirectory.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./": "./"
}
}
//// [index.js]
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
export declare const a: import("inner/other.js").Thing;

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner/index.js")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner/index.js")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner/index.js" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner/index.js")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner/index.js") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner/index.js") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner/index.js" : "inner/index.js"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,32 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
==== tests/cases/conformance/node/index.ts (1 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner/index.js")).x();
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./": "./"
}
}

View File

@ -0,0 +1,36 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationDirectory.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./": "./"
}
}
//// [index.js]
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
export declare const a: import("inner/other.js").Thing;

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner/index.js")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner/index.js")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner/index.js" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner/index.js")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner/index.js") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner/index.js") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner/index.js" : "inner/index.js"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,38 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
tests/cases/conformance/node/index.ts(3,19): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/node/index.ts(3,32): error TS2307: Cannot find module 'inner/index.js' or its corresponding type declarations.
==== tests/cases/conformance/node/index.ts (3 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner/index.js")).x();
~~~~~
!!! error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.
~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/index.js' or its corresponding type declarations.
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./*.js": "./*.js"
}
}

View File

@ -0,0 +1,36 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationPattern.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./*.js": "./*.js"
}
}
//// [index.js]
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
export declare const a: any;

View File

@ -0,0 +1,22 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner/index.js")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner/index.js")).x();
>a : any
>(await import("inner/index.js")).x() : any
>(await import("inner/index.js")).x : any
>(await import("inner/index.js")) : any
>await import("inner/index.js") : any
>import("inner/index.js") : Promise<any>
>"inner/index.js" : "inner/index.js"
>x : any
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,32 @@
tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
==== tests/cases/conformance/node/index.ts (1 errors) ====
// esm format file
import { Thing } from "inner/other";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'inner/other' or its corresponding type declarations.
export const a = (await import("inner/index.js")).x();
==== tests/cases/conformance/node/node_modules/inner/index.d.ts (0 errors) ====
// esm format file
export { x } from "./other.js";
==== tests/cases/conformance/node/node_modules/inner/other.d.ts (0 errors) ====
// esm format file
export interface Thing {}
export const x: () => Thing;
==== tests/cases/conformance/node/package.json (0 errors) ====
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ====
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./*.js": "./*.js"
}
}

View File

@ -0,0 +1,36 @@
//// [tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationPattern.ts] ////
//// [index.ts]
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [other.d.ts]
// esm format file
export interface Thing {}
export const x: () => Thing;
//// [package.json]
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
//// [package.json]
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./*.js": "./*.js"
}
}
//// [index.js]
export const a = (await import("inner/index.js")).x();
//// [index.d.ts]
export declare const a: import("inner/other.js").Thing;

View File

@ -0,0 +1,25 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : Symbol(Thing, Decl(index.ts, 1, 8))
export const a = (await import("inner/index.js")).x();
>a : Symbol(a, Decl(index.ts, 2, 12))
>(await import("inner/index.js")).x : Symbol(x, Decl(index.d.ts, 1, 8))
>"inner/index.js" : Symbol("tests/cases/conformance/node/node_modules/inner/index", Decl(index.d.ts, 0, 0))
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : Symbol(x, Decl(index.d.ts, 1, 8))
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))
export const x: () => Thing;
>x : Symbol(x, Decl(other.d.ts, 2, 12))
>Thing : Symbol(Thing, Decl(other.d.ts, 0, 0))

View File

@ -0,0 +1,26 @@
=== tests/cases/conformance/node/index.ts ===
// esm format file
import { Thing } from "inner/other";
>Thing : any
export const a = (await import("inner/index.js")).x();
>a : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x() : import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")).x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
>(await import("inner/index.js")) : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>await import("inner/index.js") : typeof import("tests/cases/conformance/node/node_modules/inner/index")
>import("inner/index.js") : Promise<typeof import("tests/cases/conformance/node/node_modules/inner/index")>
>"inner/index.js" : "inner/index.js"
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/index.d.ts ===
// esm format file
export { x } from "./other.js";
>x : () => import("tests/cases/conformance/node/node_modules/inner/other").Thing
=== tests/cases/conformance/node/node_modules/inner/other.d.ts ===
// esm format file
export interface Thing {}
export const x: () => Thing;
>x : () => Thing

View File

@ -0,0 +1,405 @@
Input::
//// [/lib/lib.d.ts]
//// [/lib/lib.es2020.full.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
//// [/src/src-dogs/dog.ts]
import { DogConfig } from 'src-types';
import { DOG_CONFIG } from './dogconfig.js';
export abstract class Dog {
public static getCapabilities(): DogConfig {
return DOG_CONFIG;
}
}
//// [/src/src-dogs/dogconfig.ts]
import { DogConfig } from 'src-types';
export const DOG_CONFIG: DogConfig = {
name: 'Default dog',
};
//// [/src/src-dogs/index.ts]
export * from 'src-types';
export * from './lassie/lassiedog.js';
//// [/src/src-dogs/lassie/lassieconfig.ts]
import { DogConfig } from 'src-types';
export const LASSIE_CONFIG: DogConfig = { name: 'Lassie' };
//// [/src/src-dogs/lassie/lassiedog.ts]
import { Dog } from '../dog.js';
import { LASSIE_CONFIG } from './lassieconfig.js';
export class LassieDog extends Dog {
protected static getDogConfig = () => LASSIE_CONFIG;
}
//// [/src/src-dogs/node_modules] symlink(/src)
//// [/src/src-dogs/package.json]
{
"type": "module",
"exports": "./index.js"
}
//// [/src/src-dogs/tsconfig.json]
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../src-types" }
],
"include": [
"**/*"
]
}
//// [/src/src-types/dogconfig.ts]
export interface DogConfig {
name: string;
}
//// [/src/src-types/index.ts]
export * from './dogconfig.js';
//// [/src/src-types/node_modules] symlink(/src)
//// [/src/src-types/package.json]
{
"type": "module",
"exports": "./index.js"
}
//// [/src/src-types/tsconfig.json]
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"composite": true
},
"include": [
"**/*"
]
}
//// [/src/tsconfig-base.json]
{
"compilerOptions": {
"declaration": true,
"module": "node12"
}
}
Output::
/lib/tsc -b src/src-types src/src-dogs --verbose
[12:00:00 AM] Projects in this build:
* src/src-types/tsconfig.json
* src/src-dogs/tsconfig.json
[12:00:00 AM] Project 'src/src-types/tsconfig.json' is out of date because output file 'src/src-types/dogconfig.js' does not exist
[12:00:00 AM] Building project '/src/src-types/tsconfig.json'...
[12:00:00 AM] Project 'src/src-dogs/tsconfig.json' is out of date because output file 'src/src-dogs/dog.js' does not exist
[12:00:00 AM] Building project '/src/src-dogs/tsconfig.json'...
exitCode:: ExitStatus.Success
//// [/src/src-dogs/dog.d.ts]
import { DogConfig } from 'src-types';
export declare abstract class Dog {
static getCapabilities(): DogConfig;
}
//// [/src/src-dogs/dog.js]
import { DOG_CONFIG } from './dogconfig.js';
export class Dog {
static getCapabilities() {
return DOG_CONFIG;
}
}
//// [/src/src-dogs/dogconfig.d.ts]
import { DogConfig } from 'src-types';
export declare const DOG_CONFIG: DogConfig;
//// [/src/src-dogs/dogconfig.js]
export const DOG_CONFIG = {
name: 'Default dog',
};
//// [/src/src-dogs/index.d.ts]
export * from 'src-types';
export * from './lassie/lassiedog.js';
//// [/src/src-dogs/index.js]
export * from 'src-types';
export * from './lassie/lassiedog.js';
//// [/src/src-dogs/lassie/lassieconfig.d.ts]
import { DogConfig } from 'src-types';
export declare const LASSIE_CONFIG: DogConfig;
//// [/src/src-dogs/lassie/lassieconfig.js]
export const LASSIE_CONFIG = { name: 'Lassie' };
//// [/src/src-dogs/lassie/lassiedog.d.ts]
import { Dog } from '../dog.js';
export declare class LassieDog extends Dog {
protected static getDogConfig: () => import("../index.js").DogConfig;
}
//// [/src/src-dogs/lassie/lassiedog.js]
import { Dog } from '../dog.js';
import { LASSIE_CONFIG } from './lassieconfig.js';
export class LassieDog extends Dog {
}
LassieDog.getDogConfig = () => LASSIE_CONFIG;
//// [/src/src-dogs/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../lib/lib.es2020.full.d.ts","../src-types/dogconfig.d.ts","../src-types/index.d.ts","./dogconfig.ts","./dog.ts","./lassie/lassieconfig.ts","./lassie/lassiedog.ts","./index.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true,"impliedFormat":1},"-2632060142-export interface DogConfig {\r\n name: string;\r\n}\r\n","-5608794531-export * from './dogconfig.js';\r\n","1966273863-import { DogConfig } from 'src-types';\n\nexport const DOG_CONFIG: DogConfig = {\n name: 'Default dog',\n};\n","6091345804-import { DogConfig } from 'src-types';\nimport { DOG_CONFIG } from './dogconfig.js';\n\nexport abstract class Dog {\n\n public static getCapabilities(): DogConfig {\n return DOG_CONFIG;\n }\n}\n","4440579024-import { DogConfig } from 'src-types';\n\nexport const LASSIE_CONFIG: DogConfig = { name: 'Lassie' };\n","-32303727812-import { Dog } from '../dog.js';\nimport { LASSIE_CONFIG } from './lassieconfig.js';\n\nexport class LassieDog extends Dog {\n protected static getDogConfig = () => LASSIE_CONFIG;\n}\n","-15974991320-export * from 'src-types';\nexport * from './lassie/lassiedog.js';\n"],"options":{"composite":true,"declaration":true,"module":100},"fileIdsList":[[3,4],[3],[3,7],[5,6],[2]],"referencedMap":[[5,1],[4,2],[8,3],[6,2],[7,4],[3,5]],"exportedModulesMap":[[5,1],[4,2],[8,3],[6,2],[7,4],[3,5]],"semanticDiagnosticsPerFile":[1,5,4,8,6,7,2,3]},"version":"FakeTSVersion"}
//// [/src/src-dogs/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../lib/lib.es2020.full.d.ts",
"../src-types/dogconfig.d.ts",
"../src-types/index.d.ts",
"./dogconfig.ts",
"./dog.ts",
"./lassie/lassieconfig.ts",
"./lassie/lassiedog.ts",
"./index.ts"
],
"fileNamesList": [
[
"../src-types/index.d.ts",
"./dogconfig.ts"
],
[
"../src-types/index.d.ts"
],
[
"../src-types/index.d.ts",
"./lassie/lassiedog.ts"
],
[
"./dog.ts",
"./lassie/lassieconfig.ts"
],
[
"../src-types/dogconfig.d.ts"
]
],
"fileInfos": {
"../../lib/lib.es2020.full.d.ts": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true,
"impliedFormat": 1
},
"../src-types/dogconfig.d.ts": {
"version": "-2632060142-export interface DogConfig {\r\n name: string;\r\n}\r\n",
"signature": "-2632060142-export interface DogConfig {\r\n name: string;\r\n}\r\n"
},
"../src-types/index.d.ts": {
"version": "-5608794531-export * from './dogconfig.js';\r\n",
"signature": "-5608794531-export * from './dogconfig.js';\r\n"
},
"./dogconfig.ts": {
"version": "1966273863-import { DogConfig } from 'src-types';\n\nexport const DOG_CONFIG: DogConfig = {\n name: 'Default dog',\n};\n",
"signature": "1966273863-import { DogConfig } from 'src-types';\n\nexport const DOG_CONFIG: DogConfig = {\n name: 'Default dog',\n};\n"
},
"./dog.ts": {
"version": "6091345804-import { DogConfig } from 'src-types';\nimport { DOG_CONFIG } from './dogconfig.js';\n\nexport abstract class Dog {\n\n public static getCapabilities(): DogConfig {\n return DOG_CONFIG;\n }\n}\n",
"signature": "6091345804-import { DogConfig } from 'src-types';\nimport { DOG_CONFIG } from './dogconfig.js';\n\nexport abstract class Dog {\n\n public static getCapabilities(): DogConfig {\n return DOG_CONFIG;\n }\n}\n"
},
"./lassie/lassieconfig.ts": {
"version": "4440579024-import { DogConfig } from 'src-types';\n\nexport const LASSIE_CONFIG: DogConfig = { name: 'Lassie' };\n",
"signature": "4440579024-import { DogConfig } from 'src-types';\n\nexport const LASSIE_CONFIG: DogConfig = { name: 'Lassie' };\n"
},
"./lassie/lassiedog.ts": {
"version": "-32303727812-import { Dog } from '../dog.js';\nimport { LASSIE_CONFIG } from './lassieconfig.js';\n\nexport class LassieDog extends Dog {\n protected static getDogConfig = () => LASSIE_CONFIG;\n}\n",
"signature": "-32303727812-import { Dog } from '../dog.js';\nimport { LASSIE_CONFIG } from './lassieconfig.js';\n\nexport class LassieDog extends Dog {\n protected static getDogConfig = () => LASSIE_CONFIG;\n}\n"
},
"./index.ts": {
"version": "-15974991320-export * from 'src-types';\nexport * from './lassie/lassiedog.js';\n",
"signature": "-15974991320-export * from 'src-types';\nexport * from './lassie/lassiedog.js';\n"
}
},
"options": {
"composite": true,
"declaration": true,
"module": 100
},
"referencedMap": {
"./dog.ts": [
"../src-types/index.d.ts",
"./dogconfig.ts"
],
"./dogconfig.ts": [
"../src-types/index.d.ts"
],
"./index.ts": [
"../src-types/index.d.ts",
"./lassie/lassiedog.ts"
],
"./lassie/lassieconfig.ts": [
"../src-types/index.d.ts"
],
"./lassie/lassiedog.ts": [
"./dog.ts",
"./lassie/lassieconfig.ts"
],
"../src-types/index.d.ts": [
"../src-types/dogconfig.d.ts"
]
},
"exportedModulesMap": {
"./dog.ts": [
"../src-types/index.d.ts",
"./dogconfig.ts"
],
"./dogconfig.ts": [
"../src-types/index.d.ts"
],
"./index.ts": [
"../src-types/index.d.ts",
"./lassie/lassiedog.ts"
],
"./lassie/lassieconfig.ts": [
"../src-types/index.d.ts"
],
"./lassie/lassiedog.ts": [
"./dog.ts",
"./lassie/lassieconfig.ts"
],
"../src-types/index.d.ts": [
"../src-types/dogconfig.d.ts"
]
},
"semanticDiagnosticsPerFile": [
"../../lib/lib.es2020.full.d.ts",
"./dog.ts",
"./dogconfig.ts",
"./index.ts",
"./lassie/lassieconfig.ts",
"./lassie/lassiedog.ts",
"../src-types/dogconfig.d.ts",
"../src-types/index.d.ts"
]
},
"version": "FakeTSVersion",
"size": 1802
}
//// [/src/src-types/dogconfig.d.ts]
export interface DogConfig {
name: string;
}
//// [/src/src-types/dogconfig.js]
export {};
//// [/src/src-types/index.d.ts]
export * from './dogconfig.js';
//// [/src/src-types/index.js]
export * from './dogconfig.js';
//// [/src/src-types/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../lib/lib.es2020.full.d.ts","./dogconfig.ts","./index.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true,"impliedFormat":1},"-5575793279-export interface DogConfig {\n name: string;\n}","-6189272282-export * from './dogconfig.js';"],"options":{"composite":true,"declaration":true,"module":100},"fileIdsList":[[2]],"referencedMap":[[3,1]],"exportedModulesMap":[[3,1]],"semanticDiagnosticsPerFile":[1,2,3]},"version":"FakeTSVersion"}
//// [/src/src-types/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../lib/lib.es2020.full.d.ts",
"./dogconfig.ts",
"./index.ts"
],
"fileNamesList": [
[
"./dogconfig.ts"
]
],
"fileInfos": {
"../../lib/lib.es2020.full.d.ts": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true,
"impliedFormat": 1
},
"./dogconfig.ts": {
"version": "-5575793279-export interface DogConfig {\n name: string;\n}",
"signature": "-5575793279-export interface DogConfig {\n name: string;\n}"
},
"./index.ts": {
"version": "-6189272282-export * from './dogconfig.js';",
"signature": "-6189272282-export * from './dogconfig.js';"
}
},
"options": {
"composite": true,
"declaration": true,
"module": 100
},
"referencedMap": {
"./index.ts": [
"./dogconfig.ts"
]
},
"exportedModulesMap": {
"./index.ts": [
"./dogconfig.ts"
]
},
"semanticDiagnosticsPerFile": [
"../../lib/lib.es2020.full.d.ts",
"./dogconfig.ts",
"./index.ts"
]
},
"version": "FakeTSVersion",
"size": 829
}

View File

@ -0,0 +1,27 @@
// @module: node12,nodenext
// @declaration: true
// @filename: index.ts
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner")).x();
// @filename: node_modules/inner/index.d.ts
// esm format file
export { x } from "./other.js";
// @filename: node_modules/inner/other.d.ts
// esm format file
export interface Thing {}
export const x: () => Thing;
// @filename: package.json
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
// @filename: node_modules/inner/package.json
{
"name": "inner",
"private": true,
"type": "module",
"exports": "./index.js"
}

View File

@ -0,0 +1,34 @@
// @module: node12,nodenext
// @declaration: true
// @filename: index.ts
// esm format file
import { Thing } from "inner/other.js"; // should fail
export const a = (await import("inner")).x();
// @filename: node_modules/inner/index.d.ts
// esm format file
export { x } from "./other.js";
// @filename: node_modules/inner/other.d.ts
// esm format file
export interface Thing {}
export const x: () => Thing;
// @filename: package.json
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
// @filename: node_modules/inner/package.json
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
".": {
"default": "./index.js"
},
"./other": {
"default": "./other.js"
}
}
}

View File

@ -0,0 +1,29 @@
// @module: node12,nodenext
// @declaration: true
// @filename: index.ts
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
// @filename: node_modules/inner/index.d.ts
// esm format file
export { x } from "./other.js";
// @filename: node_modules/inner/other.d.ts
// esm format file
export interface Thing {}
export const x: () => Thing;
// @filename: package.json
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
// @filename: node_modules/inner/package.json
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./": "./"
}
}

View File

@ -0,0 +1,29 @@
// @module: node12,nodenext
// @declaration: true
// @filename: index.ts
// esm format file
import { Thing } from "inner/other";
export const a = (await import("inner/index.js")).x();
// @filename: node_modules/inner/index.d.ts
// esm format file
export { x } from "./other.js";
// @filename: node_modules/inner/other.d.ts
// esm format file
export interface Thing {}
export const x: () => Thing;
// @filename: package.json
{
"name": "package",
"private": true,
"type": "module",
"exports": "./index.js"
}
// @filename: node_modules/inner/package.json
{
"name": "inner",
"private": true,
"type": "module",
"exports": {
"./*.js": "./*.js"
}
}