diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 18078339d8488..36047c26f0c0d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1635,7 +1635,7 @@ namespace ts { if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value && !(originalLocation!.flags & NodeFlags.JSDoc)) { const merged = getMergedSymbol(result); if (length(merged.declarations) && every(merged.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) { - error(errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); // TODO: GH#18217 + errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); } } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 12a20e0df42e1..6ed4aaf2378ce 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -575,6 +575,13 @@ namespace ts { category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Do_not_resolve_the_real_path_of_symlinks, }, + { + name: "allowUmdGlobalAccess", + type: "boolean", + affectsSemanticDiagnostics: true, + category: Diagnostics.Module_Resolution_Options, + description: Diagnostics.Allow_accessing_UMD_globals_from_modules, + }, // Source Maps { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7717f51bd50fe..09a28e00fd792 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4938,5 +4938,9 @@ "Convert parameters to destructured object": { "category": "Message", "code": 95075 + }, + "Allow accessing UMD globals from modules.": { + "category": "Message", + "code": 95076 } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 55492081050a8..7a554a8745eb6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4580,6 +4580,7 @@ namespace ts { allowJs?: boolean; /*@internal*/ allowNonTsExtensions?: boolean; allowSyntheticDefaultImports?: boolean; + allowUmdGlobalAccess?: boolean; allowUnreachableCode?: boolean; allowUnusedLabels?: boolean; alwaysStrict?: boolean; // Always combine with strict property diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 46cd79bf77dfc..e4e05ad62d388 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2489,6 +2489,7 @@ declare namespace ts { interface CompilerOptions { allowJs?: boolean; allowSyntheticDefaultImports?: boolean; + allowUmdGlobalAccess?: boolean; allowUnreachableCode?: boolean; allowUnusedLabels?: boolean; alwaysStrict?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 51c10fdf1956e..4906c6b3b32e0 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2489,6 +2489,7 @@ declare namespace ts { interface CompilerOptions { allowJs?: boolean; allowSyntheticDefaultImports?: boolean; + allowUmdGlobalAccess?: boolean; allowUnreachableCode?: boolean; allowUnusedLabels?: boolean; alwaysStrict?: boolean; diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowUmdGlobalAccess/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowUmdGlobalAccess/tsconfig.json new file mode 100644 index 0000000000000..fdd388c331200 --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowUmdGlobalAccess/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "allowUmdGlobalAccess": true + } +} diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 8e4ff5171868d..36311335115d5 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json index 7332496971fba..88f400655955b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index ebf7070cfa4d4..5095e9f81c621 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 25f9b39967a8d..46e7b4f13cde1 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index fc1fb8ec631d8..0355dd9d051ba 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index dcff85de986d4..e62bf4a08818e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 8e4ff5171868d..36311335115d5 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 112be7a95f953..3bf9d892a2461 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 4c4b740a12284..35c5bfd08ffb3 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -48,6 +48,7 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ diff --git a/tests/baselines/reference/umd9.js b/tests/baselines/reference/umd9.js new file mode 100644 index 0000000000000..99660aebb4cd5 --- /dev/null +++ b/tests/baselines/reference/umd9.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/externalModules/umd9.ts] //// + +//// [foo.d.ts] +declare class Thing { + foo(): number; +} +export = Thing; +export as namespace Foo; + +//// [a.ts] +/// +export const x = Foo; // OK in value position because allowUmdGlobalAccess: true + + +//// [a.js] +"use strict"; +exports.__esModule = true; +/// +exports.x = Foo; // OK in value position because allowUmdGlobalAccess: true diff --git a/tests/baselines/reference/umd9.symbols b/tests/baselines/reference/umd9.symbols new file mode 100644 index 0000000000000..013636f5edb5d --- /dev/null +++ b/tests/baselines/reference/umd9.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +export const x = Foo; // OK in value position because allowUmdGlobalAccess: true +>x : Symbol(x, Decl(a.ts, 1, 12)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 3, 15)) + +=== tests/cases/conformance/externalModules/foo.d.ts === +declare class Thing { +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + + foo(): number; +>foo : Symbol(Thing.foo, Decl(foo.d.ts, 0, 21)) +} +export = Thing; +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + +export as namespace Foo; +>Foo : Symbol(Foo, Decl(foo.d.ts, 3, 15)) + diff --git a/tests/baselines/reference/umd9.types b/tests/baselines/reference/umd9.types new file mode 100644 index 0000000000000..e4fc9376efdad --- /dev/null +++ b/tests/baselines/reference/umd9.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +export const x = Foo; // OK in value position because allowUmdGlobalAccess: true +>x : typeof Thing +>Foo : typeof Thing + +=== tests/cases/conformance/externalModules/foo.d.ts === +declare class Thing { +>Thing : Thing + + foo(): number; +>foo : () => number +} +export = Thing; +>Thing : Thing + +export as namespace Foo; +>Foo : typeof Thing + diff --git a/tests/cases/conformance/externalModules/umd9.ts b/tests/cases/conformance/externalModules/umd9.ts new file mode 100644 index 0000000000000..459227e9454c5 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd9.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @noImplicitReferences: true +// @allowUmdGlobalAccess: true + +// @filename: foo.d.ts +declare class Thing { + foo(): number; +} +export = Thing; +export as namespace Foo; + +// @filename: a.ts +/// +export const x = Foo; // OK in value position because allowUmdGlobalAccess: true