diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 4ee8195cbd57c..9dd6db37790a0 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -995,7 +995,7 @@ namespace ts { } else { forEach(options.lib, (libFileName, index) => { - processRootFile(combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile, index }); + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile, index }); }); } } @@ -1737,7 +1737,7 @@ namespace ts { return equalityComparer(file.fileName, getDefaultLibraryFileName()); } else { - return some(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); + return some(options.lib, libFileName => equalityComparer(file.fileName, pathForLibFile(libFileName))); } } @@ -2406,7 +2406,7 @@ namespace ts { const libName = toFileNameLowerCase(ref.fileName); const libFileName = libMap.get(libName); if (libFileName) { - return getSourceFile(combinePaths(defaultLibraryPath, libFileName)); + return getSourceFile(pathForLibFile(libFileName)); } } @@ -2883,13 +2883,32 @@ namespace ts { } } + function pathForLibFile(libFileName: string): string { + // Support resolving to lib.dom.d.ts -> @typescript/dom, and + // lib.dom.iterable.d.ts -> @typescript/dom/iterable + // lib.es2015.symbol.wellknown.d.ts -> @typescript/es2015/symbol-wellknown + const components = libFileName.split("."); + let path = components[1]; + let i = 2; + while (components[i] && components[i] !== "d") { + path += (i === 2 ? "/" : "-") + components[i]; + i++; + } + const resolveFrom = combinePaths(currentDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`); + const localOverrideModuleResult = resolveModuleName("@typescript/" + path, resolveFrom, { moduleResolution: ModuleResolutionKind.NodeJs }, host, moduleResolutionCache); + if (localOverrideModuleResult?.resolvedModule) { + return localOverrideModuleResult.resolvedModule.resolvedFileName; + } + return combinePaths(defaultLibraryPath, libFileName); + } + function processLibReferenceDirectives(file: SourceFile) { forEach(file.libReferenceDirectives, (libReference, index) => { const libName = toFileNameLowerCase(libReference.fileName); const libFileName = libMap.get(libName); if (libFileName) { // we ignore any 'no-default-lib' reference set on this file. - processRootFile(combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }); + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }); } else { const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts"); diff --git a/tests/baselines/reference/libTypeScriptOverrideSimple.errors.txt b/tests/baselines/reference/libTypeScriptOverrideSimple.errors.txt new file mode 100644 index 0000000000000..cf5912eb2769d --- /dev/null +++ b/tests/baselines/reference/libTypeScriptOverrideSimple.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/index.ts(6,1): error TS2304: Cannot find name 'window'. + + +==== /node_modules/@typescript/dom/index.d.ts (0 errors) ==== + interface ABC { abc: string } +==== tests/cases/compiler/index.ts (1 errors) ==== + /// + const a: ABC = { abc: "Hello" } + + // This should fail because libdom has been replaced + // by the module above ^ + window.localStorage + ~~~~~~ +!!! error TS2304: Cannot find name 'window'. \ No newline at end of file diff --git a/tests/baselines/reference/libTypeScriptOverrideSimple.js b/tests/baselines/reference/libTypeScriptOverrideSimple.js new file mode 100644 index 0000000000000..ae95b842125f5 --- /dev/null +++ b/tests/baselines/reference/libTypeScriptOverrideSimple.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/libTypeScriptOverrideSimple.ts] //// + +//// [index.d.ts] +interface ABC { abc: string } +//// [index.ts] +/// +const a: ABC = { abc: "Hello" } + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage + +//// [index.js] +/// +var a = { abc: "Hello" }; +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage; diff --git a/tests/baselines/reference/libTypeScriptOverrideSimple.symbols b/tests/baselines/reference/libTypeScriptOverrideSimple.symbols new file mode 100644 index 0000000000000..37c7ca70cbe8d --- /dev/null +++ b/tests/baselines/reference/libTypeScriptOverrideSimple.symbols @@ -0,0 +1,15 @@ +=== /node_modules/@typescript/dom/index.d.ts === +interface ABC { abc: string } +>ABC : Symbol(ABC, Decl(index.d.ts, 0, 0)) +>abc : Symbol(ABC.abc, Decl(index.d.ts, 0, 15)) + +=== tests/cases/compiler/index.ts === +/// +const a: ABC = { abc: "Hello" } +>a : Symbol(a, Decl(index.ts, 1, 5)) +>ABC : Symbol(ABC, Decl(index.d.ts, 0, 0)) +>abc : Symbol(abc, Decl(index.ts, 1, 16)) + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage diff --git a/tests/baselines/reference/libTypeScriptOverrideSimple.types b/tests/baselines/reference/libTypeScriptOverrideSimple.types new file mode 100644 index 0000000000000..65a28d7093d1d --- /dev/null +++ b/tests/baselines/reference/libTypeScriptOverrideSimple.types @@ -0,0 +1,19 @@ +=== /node_modules/@typescript/dom/index.d.ts === +interface ABC { abc: string } +>abc : string + +=== tests/cases/compiler/index.ts === +/// +const a: ABC = { abc: "Hello" } +>a : ABC +>{ abc: "Hello" } : { abc: string; } +>abc : string +>"Hello" : "Hello" + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage +>window.localStorage : any +>window : any +>localStorage : any + diff --git a/tests/baselines/reference/libTypeScriptSubfileResolving.errors.txt b/tests/baselines/reference/libTypeScriptSubfileResolving.errors.txt new file mode 100644 index 0000000000000..b2f731e2897da --- /dev/null +++ b/tests/baselines/reference/libTypeScriptSubfileResolving.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/index.ts(6,1): error TS2304: Cannot find name 'window'. + + +==== /node_modules/@typescript/dom/index.d.ts (0 errors) ==== + // NOOP +==== /node_modules/@typescript/dom/iterable.d.ts (0 errors) ==== + interface DOMIterable { abc: string } +==== tests/cases/compiler/index.ts (1 errors) ==== + /// + const a: DOMIterable = { abc: "Hello" } + + // This should fail because libdom has been replaced + // by the module above ^ + window.localStorage + ~~~~~~ +!!! error TS2304: Cannot find name 'window'. \ No newline at end of file diff --git a/tests/baselines/reference/libTypeScriptSubfileResolving.js b/tests/baselines/reference/libTypeScriptSubfileResolving.js new file mode 100644 index 0000000000000..d975c3669c088 --- /dev/null +++ b/tests/baselines/reference/libTypeScriptSubfileResolving.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/libTypeScriptSubfileResolving.ts] //// + +//// [index.d.ts] +// NOOP +//// [iterable.d.ts] +interface DOMIterable { abc: string } +//// [index.ts] +/// +const a: DOMIterable = { abc: "Hello" } + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage + +//// [index.js] +/// +var a = { abc: "Hello" }; +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage; diff --git a/tests/baselines/reference/libTypeScriptSubfileResolving.symbols b/tests/baselines/reference/libTypeScriptSubfileResolving.symbols new file mode 100644 index 0000000000000..3bde25ae5b7e2 --- /dev/null +++ b/tests/baselines/reference/libTypeScriptSubfileResolving.symbols @@ -0,0 +1,17 @@ +=== /node_modules/@typescript/dom/index.d.ts === +// NOOP +No type information for this code.=== /node_modules/@typescript/dom/iterable.d.ts === +interface DOMIterable { abc: string } +>DOMIterable : Symbol(DOMIterable, Decl(iterable.d.ts, 0, 0)) +>abc : Symbol(DOMIterable.abc, Decl(iterable.d.ts, 0, 23)) + +=== tests/cases/compiler/index.ts === +/// +const a: DOMIterable = { abc: "Hello" } +>a : Symbol(a, Decl(index.ts, 1, 5)) +>DOMIterable : Symbol(DOMIterable, Decl(iterable.d.ts, 0, 0)) +>abc : Symbol(abc, Decl(index.ts, 1, 24)) + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage diff --git a/tests/baselines/reference/libTypeScriptSubfileResolving.types b/tests/baselines/reference/libTypeScriptSubfileResolving.types new file mode 100644 index 0000000000000..7fe3c02924cbc --- /dev/null +++ b/tests/baselines/reference/libTypeScriptSubfileResolving.types @@ -0,0 +1,21 @@ +=== /node_modules/@typescript/dom/index.d.ts === +// NOOP +No type information for this code.=== /node_modules/@typescript/dom/iterable.d.ts === +interface DOMIterable { abc: string } +>abc : string + +=== tests/cases/compiler/index.ts === +/// +const a: DOMIterable = { abc: "Hello" } +>a : DOMIterable +>{ abc: "Hello" } : { abc: string; } +>abc : string +>"Hello" : "Hello" + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage +>window.localStorage : any +>window : any +>localStorage : any + diff --git a/tests/cases/compiler/libTypeScriptOverrideSimple.ts b/tests/cases/compiler/libTypeScriptOverrideSimple.ts new file mode 100644 index 0000000000000..4ba67cd0c0181 --- /dev/null +++ b/tests/cases/compiler/libTypeScriptOverrideSimple.ts @@ -0,0 +1,9 @@ +// @Filename: /node_modules/@typescript/dom/index.d.ts +interface ABC { abc: string } +// @Filename: index.ts +/// +const a: ABC = { abc: "Hello" } + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage \ No newline at end of file diff --git a/tests/cases/compiler/libTypeScriptSubfileResolving.ts b/tests/cases/compiler/libTypeScriptSubfileResolving.ts new file mode 100644 index 0000000000000..901d86a236aba --- /dev/null +++ b/tests/cases/compiler/libTypeScriptSubfileResolving.ts @@ -0,0 +1,11 @@ +// @Filename: /node_modules/@typescript/dom/index.d.ts +// NOOP +// @Filename: /node_modules/@typescript/dom/iterable.d.ts +interface DOMIterable { abc: string } +// @Filename: index.ts +/// +const a: DOMIterable = { abc: "Hello" } + +// This should fail because libdom has been replaced +// by the module above ^ +window.localStorage \ No newline at end of file