From 39f5dbff4345e9dbfb30e14917f2dc4a137b6cac Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 31 May 2022 14:10:17 -0700 Subject: [PATCH 01/17] Fix index fallback of CJS package from ESM-mode import when `main` is present but does not resolve (#49327) --- src/compiler/moduleNameResolver.ts | 4 +- ...ortModeImplicitIndexResolution2.errors.txt | 44 +++++++++++++++++++ ...eNextImportModeImplicitIndexResolution2.js | 44 +++++++++++++++++++ ...ImportModeImplicitIndexResolution2.symbols | 38 ++++++++++++++++ ...xtImportModeImplicitIndexResolution2.types | 38 ++++++++++++++++ ...eNextImportModeImplicitIndexResolution2.ts | 37 ++++++++++++++++ 6 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.errors.txt create mode 100644 tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.js create mode 100644 tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.symbols create mode 100644 tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.types create mode 100644 tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index d2b0db1041b..fc62e3ee01b 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2413,8 +2413,8 @@ namespace ts { ); if ( !pathAndExtension && packageInfo - && packageInfo.packageJsonContent.exports === undefined - && packageInfo.packageJsonContent.main === undefined + // eslint-disable-next-line no-null/no-null + && (packageInfo.packageJsonContent.exports === undefined || packageInfo.packageJsonContent.exports === null) && state.features & NodeResolutionFeatures.EsmMode ) { // EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume diff --git a/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.errors.txt b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.errors.txt new file mode 100644 index 00000000000..914722e2f4d --- /dev/null +++ b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.errors.txt @@ -0,0 +1,44 @@ +/index.cts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations. +/index.mts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations. + + +==== /node_modules/@types/dedent/package.json (0 errors) ==== + { "name": "@types/dedent", "version": "1.0.0", "main": "" } + +==== /node_modules/@types/dedent2/package.json (0 errors) ==== + { "name": "@types/dedent2", "version": "1.0.0", "main": "asdfasdfasdf" } + +==== /node_modules/@types/dedent3/package.json (0 errors) ==== + { "name": "@types/dedent3", "version": "1.0.0", "main": "asdfasdfasdf", "exports": null } + +==== /node_modules/@types/dedent4/package.json (0 errors) ==== + { "name": "@types/dedent4", "version": "1.0.0", "main": "asdfasdfasdf", "exports": "./asdfasdfasdf" } + +==== /node_modules/@types/dedent/index.d.ts (0 errors) ==== + export {}; + +==== /node_modules/@types/dedent2/index.d.ts (0 errors) ==== + export {}; + +==== /node_modules/@types/dedent3/index.d.ts (0 errors) ==== + export {}; + +==== /node_modules/@types/dedent4/index.d.ts (0 errors) ==== + export {}; + +==== /index.mts (1 errors) ==== + import dedent from "dedent"; + import dedent2 from "dedent2"; + import dedent3 from "dedent3"; + import dedent4 from "dedent4"; // Error + ~~~~~~~~~ +!!! error TS2307: Cannot find module 'dedent4' or its corresponding type declarations. + +==== /index.cts (1 errors) ==== + import dedent from "dedent"; + import dedent2 from "dedent2"; + import dedent3 from "dedent3"; + import dedent4 from "dedent4"; // Error + ~~~~~~~~~ +!!! error TS2307: Cannot find module 'dedent4' or its corresponding type declarations. + \ No newline at end of file diff --git a/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.js b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.js new file mode 100644 index 00000000000..3125a73f6e7 --- /dev/null +++ b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts] //// + +//// [package.json] +{ "name": "@types/dedent", "version": "1.0.0", "main": "" } + +//// [package.json] +{ "name": "@types/dedent2", "version": "1.0.0", "main": "asdfasdfasdf" } + +//// [package.json] +{ "name": "@types/dedent3", "version": "1.0.0", "main": "asdfasdfasdf", "exports": null } + +//// [package.json] +{ "name": "@types/dedent4", "version": "1.0.0", "main": "asdfasdfasdf", "exports": "./asdfasdfasdf" } + +//// [index.d.ts] +export {}; + +//// [index.d.ts] +export {}; + +//// [index.d.ts] +export {}; + +//// [index.d.ts] +export {}; + +//// [index.mts] +import dedent from "dedent"; +import dedent2 from "dedent2"; +import dedent3 from "dedent3"; +import dedent4 from "dedent4"; // Error + +//// [index.cts] +import dedent from "dedent"; +import dedent2 from "dedent2"; +import dedent3 from "dedent3"; +import dedent4 from "dedent4"; // Error + + +//// [index.mjs] +export {}; +//// [index.cjs] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.symbols b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.symbols new file mode 100644 index 00000000000..5685121775b --- /dev/null +++ b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.symbols @@ -0,0 +1,38 @@ +=== /node_modules/@types/dedent/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent2/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent3/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent4/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /index.mts === +import dedent from "dedent"; +>dedent : Symbol(dedent, Decl(index.mts, 0, 6)) + +import dedent2 from "dedent2"; +>dedent2 : Symbol(dedent2, Decl(index.mts, 1, 6)) + +import dedent3 from "dedent3"; +>dedent3 : Symbol(dedent3, Decl(index.mts, 2, 6)) + +import dedent4 from "dedent4"; // Error +>dedent4 : Symbol(dedent4, Decl(index.mts, 3, 6)) + +=== /index.cts === +import dedent from "dedent"; +>dedent : Symbol(dedent, Decl(index.cts, 0, 6)) + +import dedent2 from "dedent2"; +>dedent2 : Symbol(dedent2, Decl(index.cts, 1, 6)) + +import dedent3 from "dedent3"; +>dedent3 : Symbol(dedent3, Decl(index.cts, 2, 6)) + +import dedent4 from "dedent4"; // Error +>dedent4 : Symbol(dedent4, Decl(index.cts, 3, 6)) + diff --git a/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.types b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.types new file mode 100644 index 00000000000..a2a37da0ecd --- /dev/null +++ b/tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.types @@ -0,0 +1,38 @@ +=== /node_modules/@types/dedent/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent2/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent3/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /node_modules/@types/dedent4/index.d.ts === +export {}; +No type information for this code. +No type information for this code.=== /index.mts === +import dedent from "dedent"; +>dedent : typeof dedent + +import dedent2 from "dedent2"; +>dedent2 : typeof dedent2 + +import dedent3 from "dedent3"; +>dedent3 : typeof dedent3 + +import dedent4 from "dedent4"; // Error +>dedent4 : any + +=== /index.cts === +import dedent from "dedent"; +>dedent : typeof dedent + +import dedent2 from "dedent2"; +>dedent2 : typeof dedent2 + +import dedent3 from "dedent3"; +>dedent3 : typeof dedent3 + +import dedent4 from "dedent4"; // Error +>dedent4 : any + diff --git a/tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts b/tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts new file mode 100644 index 00000000000..12b7844c22b --- /dev/null +++ b/tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts @@ -0,0 +1,37 @@ +// @module: nodenext + +// @Filename: /node_modules/@types/dedent/package.json +{ "name": "@types/dedent", "version": "1.0.0", "main": "" } + +// @Filename: /node_modules/@types/dedent2/package.json +{ "name": "@types/dedent2", "version": "1.0.0", "main": "asdfasdfasdf" } + +// @Filename: /node_modules/@types/dedent3/package.json +{ "name": "@types/dedent3", "version": "1.0.0", "main": "asdfasdfasdf", "exports": null } + +// @Filename: /node_modules/@types/dedent4/package.json +{ "name": "@types/dedent4", "version": "1.0.0", "main": "asdfasdfasdf", "exports": "./asdfasdfasdf" } + +// @Filename: /node_modules/@types/dedent/index.d.ts +export {}; + +// @Filename: /node_modules/@types/dedent2/index.d.ts +export {}; + +// @Filename: /node_modules/@types/dedent3/index.d.ts +export {}; + +// @Filename: /node_modules/@types/dedent4/index.d.ts +export {}; + +// @Filename: /index.mts +import dedent from "dedent"; +import dedent2 from "dedent2"; +import dedent3 from "dedent3"; +import dedent4 from "dedent4"; // Error + +// @Filename: /index.cts +import dedent from "dedent"; +import dedent2 from "dedent2"; +import dedent3 from "dedent3"; +import dedent4 from "dedent4"; // Error From a5b1f95c23768706344064b5c7ba1a2a13c35864 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 31 May 2022 14:51:08 -0700 Subject: [PATCH 02/17] Allow accessors to override non-class or abstract properties (#41994) * remove too-late fix * Allow any property from a mapped type * turn off error for any non-class base * Also handle synthetic properties more laxly Originally from #42635, but this version is simpler. * update baselines * Update baselines * createUnionProperty of accessors creates an accessor Seems simple and doesn't break much. I need to double-check the few test failures, however. * Fix computation of write type of accessors * Calculate property-vs-accessor in existing loop Instead of looping over the props list 3 more times. * Undo synthetic accessor change * Minimise diff --- src/compiler/checker.ts | 16 ++- .../reference/accessorsOverrideProperty8.js | 50 ++++++++ .../accessorsOverrideProperty8.symbols | 93 +++++++++++++++ .../accessorsOverrideProperty8.types | 78 ++++++++++++ .../reference/accessorsOverrideProperty9.js | 79 +++++++++++++ .../accessorsOverrideProperty9.symbols | 111 ++++++++++++++++++ .../accessorsOverrideProperty9.types | 89 ++++++++++++++ .../accessorsOverrideProperty8.ts | 32 +++++ .../accessorsOverrideProperty9.ts | 49 ++++++++ 9 files changed, 593 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/accessorsOverrideProperty8.js create mode 100644 tests/baselines/reference/accessorsOverrideProperty8.symbols create mode 100644 tests/baselines/reference/accessorsOverrideProperty8.types create mode 100644 tests/baselines/reference/accessorsOverrideProperty9.js create mode 100644 tests/baselines/reference/accessorsOverrideProperty9.symbols create mode 100644 tests/baselines/reference/accessorsOverrideProperty9.types create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f352f53286d..4b178078b68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7558,7 +7558,7 @@ namespace ts { ...!length(baseTypes) ? [] : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))], ...!length(implementsExpressions) ? [] : [factory.createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)] ]; - const symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType)); + const symbolProps = getNonInheritedProperties(classType, baseTypes, getPropertiesOfType(classType)); const publicSymbolProps = filter(symbolProps, s => { // `valueDeclaration` could be undefined if inherited from // a union/intersection base type, but inherited properties @@ -40102,10 +40102,13 @@ namespace ts { const derivedPropertyFlags = derived.flags & SymbolFlags.PropertyOrAccessor; if (basePropertyFlags && derivedPropertyFlags) { // property/accessor is overridden with property/accessor - if (baseDeclarationFlags & ModifierFlags.Abstract && !(base.valueDeclaration && isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer) - || base.valueDeclaration && base.valueDeclaration.parent.kind === SyntaxKind.InterfaceDeclaration + if ((getCheckFlags(base) & CheckFlags.Synthetic + ? base.declarations?.some(d => isPropertyAbstractOrInterface(d, baseDeclarationFlags)) + : base.declarations?.every(d => isPropertyAbstractOrInterface(d, baseDeclarationFlags))) + || getCheckFlags(base) & CheckFlags.Mapped || derived.valueDeclaration && isBinaryExpression(derived.valueDeclaration)) { // when the base property is abstract or from an interface, base/derived flags don't need to match + // for intersection properties, this must be true of *any* of the declarations, for others it must be true of *all* // same when the derived property is from an assignment continue; } @@ -40163,7 +40166,12 @@ namespace ts { } } - function getNonInterhitedProperties(type: InterfaceType, baseTypes: BaseType[], properties: Symbol[]) { + function isPropertyAbstractOrInterface(declaration: Declaration, baseDeclarationFlags: ModifierFlags) { + return baseDeclarationFlags & ModifierFlags.Abstract && (!isPropertyDeclaration(declaration) || !declaration.initializer) + || isInterfaceDeclaration(declaration.parent); + } + + function getNonInheritedProperties(type: InterfaceType, baseTypes: BaseType[], properties: Symbol[]) { if (!length(baseTypes)) { return properties; } diff --git a/tests/baselines/reference/accessorsOverrideProperty8.js b/tests/baselines/reference/accessorsOverrideProperty8.js new file mode 100644 index 00000000000..bd51c4b9afb --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty8.js @@ -0,0 +1,50 @@ +//// [accessorsOverrideProperty8.ts] +type Types = 'boolean' | 'unknown' | 'string'; + +type Properties = { + readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown +} + +type AnyCtor

= new (...a: any[]) => P + +declare function classWithProperties(properties: T, klass: AnyCtor

): { + new(): P & Properties; + prototype: P & Properties +}; + +const Base = classWithProperties({ + get x() { return 'boolean' as const }, + y: 'string', +}, class Base { +}); + +class MyClass extends Base { + get x() { + return false; + } + get y() { + return 'hi' + } +} + +const mine = new MyClass(); +const value = mine.x; + + + +//// [accessorsOverrideProperty8.js] +const Base = classWithProperties({ + get x() { return 'boolean'; }, + y: 'string', +}, class Base { +}); +class MyClass extends Base { + get x() { + return false; + } + get y() { + return 'hi'; + } +} +const mine = new MyClass(); +const value = mine.x; diff --git a/tests/baselines/reference/accessorsOverrideProperty8.symbols b/tests/baselines/reference/accessorsOverrideProperty8.symbols new file mode 100644 index 00000000000..7e60b8c582d --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty8.symbols @@ -0,0 +1,93 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts === +type Types = 'boolean' | 'unknown' | 'string'; +>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0)) + +type Properties = { +>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16)) +>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 2, 29)) +>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0)) + + readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown +>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16)) +>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16)) +>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14)) +} + +type AnyCtor

= new (...a: any[]) => P +>AnyCtor : Symbol(AnyCtor, Decl(accessorsOverrideProperty8.ts, 4, 1)) +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 6, 13)) +>a : Symbol(a, Decl(accessorsOverrideProperty8.ts, 6, 38)) +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 6, 13)) + +declare function classWithProperties(properties: T, klass: AnyCtor

): { +>classWithProperties : Symbol(classWithProperties, Decl(accessorsOverrideProperty8.ts, 6, 55)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37)) +>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 8, 50)) +>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0)) +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72)) +>properties : Symbol(properties, Decl(accessorsOverrideProperty8.ts, 8, 91)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37)) +>klass : Symbol(klass, Decl(accessorsOverrideProperty8.ts, 8, 105)) +>AnyCtor : Symbol(AnyCtor, Decl(accessorsOverrideProperty8.ts, 4, 1)) +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72)) + + new(): P & Properties; +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72)) +>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37)) + + prototype: P & Properties +>prototype : Symbol(prototype, Decl(accessorsOverrideProperty8.ts, 9, 29)) +>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72)) +>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46)) +>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37)) + +}; + +const Base = classWithProperties({ +>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 13, 5)) +>classWithProperties : Symbol(classWithProperties, Decl(accessorsOverrideProperty8.ts, 6, 55)) + + get x() { return 'boolean' as const }, +>x : Symbol(x, Decl(accessorsOverrideProperty8.ts, 13, 34)) +>const : Symbol(const) + + y: 'string', +>y : Symbol(y, Decl(accessorsOverrideProperty8.ts, 14, 42)) + +}, class Base { +>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 16, 2)) + +}); + +class MyClass extends Base { +>MyClass : Symbol(MyClass, Decl(accessorsOverrideProperty8.ts, 17, 3)) +>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 13, 5)) + + get x() { +>x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28)) + + return false; + } + get y() { +>y : Symbol(MyClass.y, Decl(accessorsOverrideProperty8.ts, 22, 5)) + + return 'hi' + } +} + +const mine = new MyClass(); +>mine : Symbol(mine, Decl(accessorsOverrideProperty8.ts, 28, 5)) +>MyClass : Symbol(MyClass, Decl(accessorsOverrideProperty8.ts, 17, 3)) + +const value = mine.x; +>value : Symbol(value, Decl(accessorsOverrideProperty8.ts, 29, 5)) +>mine.x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28)) +>mine : Symbol(mine, Decl(accessorsOverrideProperty8.ts, 28, 5)) +>x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28)) + + diff --git a/tests/baselines/reference/accessorsOverrideProperty8.types b/tests/baselines/reference/accessorsOverrideProperty8.types new file mode 100644 index 00000000000..1379593d280 --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty8.types @@ -0,0 +1,78 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts === +type Types = 'boolean' | 'unknown' | 'string'; +>Types : "string" | "boolean" | "unknown" + +type Properties = { +>Properties : Properties +>key : string + + readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown +} + +type AnyCtor

= new (...a: any[]) => P +>AnyCtor : AnyCtor

+>a : any[] + +declare function classWithProperties(properties: T, klass: AnyCtor

): { +>classWithProperties : (properties: T, klass: AnyCtor

) => { new (): P & Properties; prototype: P & Properties;} +>key : string +>properties : T +>klass : AnyCtor

+ + new(): P & Properties; + prototype: P & Properties +>prototype : P & Properties + +}; + +const Base = classWithProperties({ +>Base : { new (): Base & Properties<{ readonly x: "boolean"; y: "string"; }>; prototype: Base & Properties<{ readonly x: "boolean"; y: "string"; }>; } +>classWithProperties({ get x() { return 'boolean' as const }, y: 'string',}, class Base {}) : { new (): Base & Properties<{ readonly x: "boolean"; y: "string"; }>; prototype: Base & Properties<{ readonly x: "boolean"; y: "string"; }>; } +>classWithProperties : (properties: T, klass: AnyCtor

) => { new (): P & Properties; prototype: P & Properties; } +>{ get x() { return 'boolean' as const }, y: 'string',} : { readonly x: "boolean"; y: "string"; } + + get x() { return 'boolean' as const }, +>x : "boolean" +>'boolean' as const : "boolean" +>'boolean' : "boolean" + + y: 'string', +>y : "string" +>'string' : "string" + +}, class Base { +>class Base {} : typeof Base +>Base : typeof Base + +}); + +class MyClass extends Base { +>MyClass : MyClass +>Base : Base & Properties<{ readonly x: "boolean"; y: "string"; }> + + get x() { +>x : boolean + + return false; +>false : false + } + get y() { +>y : string + + return 'hi' +>'hi' : "hi" + } +} + +const mine = new MyClass(); +>mine : MyClass +>new MyClass() : MyClass +>MyClass : typeof MyClass + +const value = mine.x; +>value : boolean +>mine.x : boolean +>mine : MyClass +>x : boolean + + diff --git a/tests/baselines/reference/accessorsOverrideProperty9.js b/tests/baselines/reference/accessorsOverrideProperty9.js new file mode 100644 index 00000000000..a1b8d7bde87 --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty9.js @@ -0,0 +1,79 @@ +//// [accessorsOverrideProperty9.ts] +// #41347, based on microsoft/rushstack + +// Mixin utilities +export type Constructor = new (...args: any[]) => T; +export type PropertiesOf = { [K in keyof T]: T[K] }; + +interface IApiItemConstructor extends Constructor, PropertiesOf {} + +// Base class +class ApiItem { + public get members(): ReadonlyArray { + return []; + } +} + +// Normal subclass +class ApiEnumMember extends ApiItem { +} + +// Mixin base class +interface ApiItemContainerMixin extends ApiItem { + readonly members: ReadonlyArray; +} + +function ApiItemContainerMixin( + baseClass: TBaseClass +): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) { + abstract class MixedClass extends baseClass implements ApiItemContainerMixin { + public constructor(...args: any[]) { + super(...args); + } + + public get members(): ReadonlyArray { + return []; + } + } + + return MixedClass; +} + +// Subclass inheriting from mixin +export class ApiEnum extends ApiItemContainerMixin(ApiItem) { + // This worked prior to TypeScript 4.0: + public get members(): ReadonlyArray { + return []; + } +} + + +//// [accessorsOverrideProperty9.js] +// #41347, based on microsoft/rushstack +// Base class +class ApiItem { + get members() { + return []; + } +} +// Normal subclass +class ApiEnumMember extends ApiItem { +} +function ApiItemContainerMixin(baseClass) { + class MixedClass extends baseClass { + constructor(...args) { + super(...args); + } + get members() { + return []; + } + } + return MixedClass; +} +// Subclass inheriting from mixin +export class ApiEnum extends ApiItemContainerMixin(ApiItem) { + // This worked prior to TypeScript 4.0: + get members() { + return []; + } +} diff --git a/tests/baselines/reference/accessorsOverrideProperty9.symbols b/tests/baselines/reference/accessorsOverrideProperty9.symbols new file mode 100644 index 00000000000..5195876798a --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty9.symbols @@ -0,0 +1,111 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts === +// #41347, based on microsoft/rushstack + +// Mixin utilities +export type Constructor = new (...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(accessorsOverrideProperty9.ts, 0, 0)) +>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 3, 24)) +>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 3, 39)) +>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 3, 24)) + +export type PropertiesOf = { [K in keyof T]: T[K] }; +>PropertiesOf : Symbol(PropertiesOf, Decl(accessorsOverrideProperty9.ts, 3, 60)) +>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25)) +>K : Symbol(K, Decl(accessorsOverrideProperty9.ts, 4, 33)) +>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25)) +>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25)) +>K : Symbol(K, Decl(accessorsOverrideProperty9.ts, 4, 33)) + +interface IApiItemConstructor extends Constructor, PropertiesOf {} +>IApiItemConstructor : Symbol(IApiItemConstructor, Decl(accessorsOverrideProperty9.ts, 4, 55)) +>Constructor : Symbol(Constructor, Decl(accessorsOverrideProperty9.ts, 0, 0)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) +>PropertiesOf : Symbol(PropertiesOf, Decl(accessorsOverrideProperty9.ts, 3, 60)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + +// Base class +class ApiItem { +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + + public get members(): ReadonlyArray { +>members : Symbol(ApiItem.members, Decl(accessorsOverrideProperty9.ts, 9, 15)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + + return []; + } +} + +// Normal subclass +class ApiEnumMember extends ApiItem { +>ApiEnumMember : Symbol(ApiEnumMember, Decl(accessorsOverrideProperty9.ts, 13, 1)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) +} + +// Mixin base class +interface ApiItemContainerMixin extends ApiItem { +>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + + readonly members: ReadonlyArray; +>members : Symbol(ApiItemContainerMixin.members, Decl(accessorsOverrideProperty9.ts, 20, 49)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) +} + +function ApiItemContainerMixin( +>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1)) +>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31)) +>IApiItemConstructor : Symbol(IApiItemConstructor, Decl(accessorsOverrideProperty9.ts, 4, 55)) + + baseClass: TBaseClass +>baseClass : Symbol(baseClass, Decl(accessorsOverrideProperty9.ts, 24, 71)) +>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31)) + +): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) { +>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31)) +>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 26, 22)) +>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1)) + + abstract class MixedClass extends baseClass implements ApiItemContainerMixin { +>MixedClass : Symbol(MixedClass, Decl(accessorsOverrideProperty9.ts, 26, 65)) +>baseClass : Symbol(baseClass, Decl(accessorsOverrideProperty9.ts, 24, 71)) +>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1)) + + public constructor(...args: any[]) { +>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 28, 23)) + + super(...args); +>super : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31)) +>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 28, 23)) + } + + public get members(): ReadonlyArray { +>members : Symbol(MixedClass.members, Decl(accessorsOverrideProperty9.ts, 30, 5)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + + return []; + } + } + + return MixedClass; +>MixedClass : Symbol(MixedClass, Decl(accessorsOverrideProperty9.ts, 26, 65)) +} + +// Subclass inheriting from mixin +export class ApiEnum extends ApiItemContainerMixin(ApiItem) { +>ApiEnum : Symbol(ApiEnum, Decl(accessorsOverrideProperty9.ts, 38, 1)) +>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1)) +>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91)) + + // This worked prior to TypeScript 4.0: + public get members(): ReadonlyArray { +>members : Symbol(ApiEnum.members, Decl(accessorsOverrideProperty9.ts, 41, 61)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --)) +>ApiEnumMember : Symbol(ApiEnumMember, Decl(accessorsOverrideProperty9.ts, 13, 1)) + + return []; + } +} + diff --git a/tests/baselines/reference/accessorsOverrideProperty9.types b/tests/baselines/reference/accessorsOverrideProperty9.types new file mode 100644 index 00000000000..dcbc3523e10 --- /dev/null +++ b/tests/baselines/reference/accessorsOverrideProperty9.types @@ -0,0 +1,89 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts === +// #41347, based on microsoft/rushstack + +// Mixin utilities +export type Constructor = new (...args: any[]) => T; +>Constructor : Constructor +>args : any[] + +export type PropertiesOf = { [K in keyof T]: T[K] }; +>PropertiesOf : PropertiesOf + +interface IApiItemConstructor extends Constructor, PropertiesOf {} +>ApiItem : typeof ApiItem + +// Base class +class ApiItem { +>ApiItem : ApiItem + + public get members(): ReadonlyArray { +>members : readonly ApiItem[] + + return []; +>[] : never[] + } +} + +// Normal subclass +class ApiEnumMember extends ApiItem { +>ApiEnumMember : ApiEnumMember +>ApiItem : ApiItem +} + +// Mixin base class +interface ApiItemContainerMixin extends ApiItem { + readonly members: ReadonlyArray; +>members : readonly ApiItem[] +} + +function ApiItemContainerMixin( +>ApiItemContainerMixin : (baseClass: TBaseClass) => TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) + + baseClass: TBaseClass +>baseClass : TBaseClass + +): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) { +>args : any[] + + abstract class MixedClass extends baseClass implements ApiItemContainerMixin { +>MixedClass : MixedClass +>baseClass : ApiItem + + public constructor(...args: any[]) { +>args : any[] + + super(...args); +>super(...args) : void +>super : TBaseClass +>...args : any +>args : any[] + } + + public get members(): ReadonlyArray { +>members : readonly ApiItem[] + + return []; +>[] : never[] + } + } + + return MixedClass; +>MixedClass : ((abstract new (...args: any[]) => MixedClass) & { prototype: ApiItemContainerMixin.MixedClass; }) & TBaseClass +} + +// Subclass inheriting from mixin +export class ApiEnum extends ApiItemContainerMixin(ApiItem) { +>ApiEnum : ApiEnum +>ApiItemContainerMixin(ApiItem) : ApiItem & ApiItemContainerMixin +>ApiItemContainerMixin : (baseClass: TBaseClass) => TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) +>ApiItem : typeof ApiItem + + // This worked prior to TypeScript 4.0: + public get members(): ReadonlyArray { +>members : readonly ApiEnumMember[] + + return []; +>[] : never[] + } +} + diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts new file mode 100644 index 00000000000..c8b02945cad --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts @@ -0,0 +1,32 @@ +// @target: es2019 +type Types = 'boolean' | 'unknown' | 'string'; + +type Properties = { + readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown +} + +type AnyCtor

= new (...a: any[]) => P + +declare function classWithProperties(properties: T, klass: AnyCtor

): { + new(): P & Properties; + prototype: P & Properties +}; + +const Base = classWithProperties({ + get x() { return 'boolean' as const }, + y: 'string', +}, class Base { +}); + +class MyClass extends Base { + get x() { + return false; + } + get y() { + return 'hi' + } +} + +const mine = new MyClass(); +const value = mine.x; + diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts new file mode 100644 index 00000000000..9dfa1a833b0 --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts @@ -0,0 +1,49 @@ +// @strict: true +// @target: es2017 +// #41347, based on microsoft/rushstack + +// Mixin utilities +export type Constructor = new (...args: any[]) => T; +export type PropertiesOf = { [K in keyof T]: T[K] }; + +interface IApiItemConstructor extends Constructor, PropertiesOf {} + +// Base class +class ApiItem { + public get members(): ReadonlyArray { + return []; + } +} + +// Normal subclass +class ApiEnumMember extends ApiItem { +} + +// Mixin base class +interface ApiItemContainerMixin extends ApiItem { + readonly members: ReadonlyArray; +} + +function ApiItemContainerMixin( + baseClass: TBaseClass +): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) { + abstract class MixedClass extends baseClass implements ApiItemContainerMixin { + public constructor(...args: any[]) { + super(...args); + } + + public get members(): ReadonlyArray { + return []; + } + } + + return MixedClass; +} + +// Subclass inheriting from mixin +export class ApiEnum extends ApiItemContainerMixin(ApiItem) { + // This worked prior to TypeScript 4.0: + public get members(): ReadonlyArray { + return []; + } +} From 3da165e3df82b35069fa9ecbce0fbfd38cf42fb9 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 1 Jun 2022 01:22:16 +0300 Subject: [PATCH 03/17] fix(49178): check expression with type arguments in inlay hints (#49179) --- src/services/inlayHints.ts | 2 +- .../cases/fourslash/inlayHintsShouldWork68.ts | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/inlayHintsShouldWork68.ts diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index ca95df202b8..e00ca3308d5 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -47,7 +47,7 @@ namespace ts.InlayHints { return; } - if (isTypeNode(node)) { + if (isTypeNode(node) && !isExpressionWithTypeArguments(node)) { return; } diff --git a/tests/cases/fourslash/inlayHintsShouldWork68.ts b/tests/cases/fourslash/inlayHintsShouldWork68.ts new file mode 100644 index 00000000000..819041f4ab3 --- /dev/null +++ b/tests/cases/fourslash/inlayHintsShouldWork68.ts @@ -0,0 +1,25 @@ +/// + +////const foo = (a = 1) => class { } +//// +////const C1 = class extends foo(/*1*/1) { } +////class C2 extends foo(/*2*/1) { } + +const markers = test.markers(); + +verify.getInlayHints([ + { + text: 'a:', + position: markers[0].position, + kind: ts.InlayHintKind.Parameter, + whitespaceAfter: true + }, + { + text: 'a:', + position: markers[1].position, + kind: ts.InlayHintKind.Parameter, + whitespaceAfter: true + }, +], undefined, { + includeInlayParameterNameHints: "literals" +}); From bf5acb5c4d56b083b55d8ecb03414e259b918d58 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 31 May 2022 15:36:13 -0700 Subject: [PATCH 04/17] Issue serialization error when attempting to serialize a late-bound name from a mapped type (#49221) --- src/compiler/checker.ts | 2 +- ...tMappedTypeTemplateTypeofSymbol.errors.txt | 25 +++++++++++++ ...ationEmitMappedTypeTemplateTypeofSymbol.js | 32 ++++++++++++++++ ...EmitMappedTypeTemplateTypeofSymbol.symbols | 35 ++++++++++++++++++ ...onEmitMappedTypeTemplateTypeofSymbol.types | 37 +++++++++++++++++++ ...ationEmitMappedTypeTemplateTypeofSymbol.ts | 19 ++++++++++ 6 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.errors.txt create mode 100644 tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.js create mode 100644 tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.symbols create mode 100644 tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.types create mode 100644 tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4b178078b68..8ae4c79370c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5622,7 +5622,7 @@ namespace ts { anyType : getNonMissingTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; - if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) { + if (context.tracker.trackSymbol && isLateBoundName(propertySymbol.escapedName)) { if (propertySymbol.declarations) { const decl = first(propertySymbol.declarations); if (hasLateBindableName(decl)) { diff --git a/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.errors.txt b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.errors.txt new file mode 100644 index 00000000000..769d1ff9d26 --- /dev/null +++ b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.errors.txt @@ -0,0 +1,25 @@ +tests/cases/compiler/b.ts(2,14): error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized. +tests/cases/compiler/c.ts(3,14): error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized. + + +==== tests/cases/compiler/a.d.ts (0 errors) ==== + export declare const timestampSymbol: unique symbol; + + export declare const Timestamp: { + [TKey in typeof timestampSymbol]: true; + }; + + export declare function now(): typeof Timestamp; + +==== tests/cases/compiler/b.ts (1 errors) ==== + import * as x from "./a"; + export const timestamp = x.now(); + ~~~~~~~~~ +!!! error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized. + +==== tests/cases/compiler/c.ts (1 errors) ==== + import { now } from "./a"; + + export const timestamp = now(); + ~~~~~~~~~ +!!! error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized. \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.js b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.js new file mode 100644 index 00000000000..981d93fc222 --- /dev/null +++ b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts] //// + +//// [a.d.ts] +export declare const timestampSymbol: unique symbol; + +export declare const Timestamp: { + [TKey in typeof timestampSymbol]: true; +}; + +export declare function now(): typeof Timestamp; + +//// [b.ts] +import * as x from "./a"; +export const timestamp = x.now(); + +//// [c.ts] +import { now } from "./a"; + +export const timestamp = now(); + +//// [b.js] +"use strict"; +exports.__esModule = true; +exports.timestamp = void 0; +var x = require("./a"); +exports.timestamp = x.now(); +//// [c.js] +"use strict"; +exports.__esModule = true; +exports.timestamp = void 0; +var a_1 = require("./a"); +exports.timestamp = (0, a_1.now)(); diff --git a/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.symbols b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.symbols new file mode 100644 index 00000000000..ba9ba5dec42 --- /dev/null +++ b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/a.d.ts === +export declare const timestampSymbol: unique symbol; +>timestampSymbol : Symbol(timestampSymbol, Decl(a.d.ts, 0, 20)) + +export declare const Timestamp: { +>Timestamp : Symbol(Timestamp, Decl(a.d.ts, 2, 20)) + + [TKey in typeof timestampSymbol]: true; +>TKey : Symbol(TKey, Decl(a.d.ts, 3, 5)) +>timestampSymbol : Symbol(timestampSymbol, Decl(a.d.ts, 0, 20)) + +}; + +export declare function now(): typeof Timestamp; +>now : Symbol(now, Decl(a.d.ts, 4, 2)) +>Timestamp : Symbol(Timestamp, Decl(a.d.ts, 2, 20)) + +=== tests/cases/compiler/b.ts === +import * as x from "./a"; +>x : Symbol(x, Decl(b.ts, 0, 6)) + +export const timestamp = x.now(); +>timestamp : Symbol(timestamp, Decl(b.ts, 1, 12)) +>x.now : Symbol(x.now, Decl(a.d.ts, 4, 2)) +>x : Symbol(x, Decl(b.ts, 0, 6)) +>now : Symbol(x.now, Decl(a.d.ts, 4, 2)) + +=== tests/cases/compiler/c.ts === +import { now } from "./a"; +>now : Symbol(now, Decl(c.ts, 0, 8)) + +export const timestamp = now(); +>timestamp : Symbol(timestamp, Decl(c.ts, 2, 12)) +>now : Symbol(now, Decl(c.ts, 0, 8)) + diff --git a/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.types b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.types new file mode 100644 index 00000000000..caaced753ee --- /dev/null +++ b/tests/baselines/reference/declarationEmitMappedTypeTemplateTypeofSymbol.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/a.d.ts === +export declare const timestampSymbol: unique symbol; +>timestampSymbol : unique symbol + +export declare const Timestamp: { +>Timestamp : { [timestampSymbol]: true; } + + [TKey in typeof timestampSymbol]: true; +>timestampSymbol : unique symbol +>true : true + +}; + +export declare function now(): typeof Timestamp; +>now : () => typeof Timestamp +>Timestamp : { [timestampSymbol]: true; } + +=== tests/cases/compiler/b.ts === +import * as x from "./a"; +>x : typeof x + +export const timestamp = x.now(); +>timestamp : { [x.timestampSymbol]: true; } +>x.now() : { [x.timestampSymbol]: true; } +>x.now : () => { [x.timestampSymbol]: true; } +>x : typeof x +>now : () => { [x.timestampSymbol]: true; } + +=== tests/cases/compiler/c.ts === +import { now } from "./a"; +>now : () => { [timestampSymbol]: true; } + +export const timestamp = now(); +>timestamp : { [timestampSymbol]: true; } +>now() : { [timestampSymbol]: true; } +>now : () => { [timestampSymbol]: true; } + diff --git a/tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts b/tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts new file mode 100644 index 00000000000..cc6118802d8 --- /dev/null +++ b/tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts @@ -0,0 +1,19 @@ +// @strict: true +// @declaration: true +// @filename: a.d.ts +export declare const timestampSymbol: unique symbol; + +export declare const Timestamp: { + [TKey in typeof timestampSymbol]: true; +}; + +export declare function now(): typeof Timestamp; + +// @filename: b.ts +import * as x from "./a"; +export const timestamp = x.now(); + +// @filename: c.ts +import { now } from "./a"; + +export const timestamp = now(); \ No newline at end of file From 44b97459420534d028d7dbc5aeed66823ee7fb89 Mon Sep 17 00:00:00 2001 From: TRCYX <2915154295@qq.com> Date: Wed, 1 Jun 2022 07:03:17 +0800 Subject: [PATCH 05/17] fix(49151): format type parameters/arguments (#49165) Before, the formatter did not consider these constructs as comma separated lists in general, leading to wrong indentation of '>' after the list. --- src/services/formatting/formatting.ts | 21 ++- .../fourslash/genericsFormattingMultiline.ts | 140 ++++++++++++++++++ 2 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/genericsFormattingMultiline.ts diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 256398d9a20..789fcb12c58 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -617,7 +617,6 @@ namespace ts.formatting { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxClosingElement: case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.ExpressionWithTypeArguments: return false; } break; @@ -835,7 +834,7 @@ namespace ts.formatting { const listEndToken = getCloseTokenForOpenToken(listStartToken); if (listEndToken !== SyntaxKind.Unknown && formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) { let tokenInfo: TokenInfo | undefined = formattingScanner.readTokenInfo(parent); - if (tokenInfo.token.kind === SyntaxKind.CommaToken && isCallLikeExpression(parent)) { + if (tokenInfo.token.kind === SyntaxKind.CommaToken) { // consume the comma consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent); tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined; @@ -1311,6 +1310,12 @@ namespace ts.formatting { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.ArrowFunction: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: if ((node as FunctionDeclaration).typeParameters === list) { return SyntaxKind.LessThanToken; } @@ -1327,7 +1332,19 @@ namespace ts.formatting { return SyntaxKind.OpenParenToken; } break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + if ((node as ClassDeclaration).typeParameters === list) { + return SyntaxKind.LessThanToken; + } + break; case SyntaxKind.TypeReference: + case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.TypeQuery: + case SyntaxKind.ExpressionWithTypeArguments: + case SyntaxKind.ImportType: if ((node as TypeReferenceNode).typeArguments === list) { return SyntaxKind.LessThanToken; } diff --git a/tests/cases/fourslash/genericsFormattingMultiline.ts b/tests/cases/fourslash/genericsFormattingMultiline.ts new file mode 100644 index 00000000000..8ee8b09a07d --- /dev/null +++ b/tests/cases/fourslash/genericsFormattingMultiline.ts @@ -0,0 +1,140 @@ +/// + +//// +//// class Foo < +//// T1 extends unknown, +//// T2 +//// > { +//// public method < +//// T3, +//// > (a: T1, b: Array < +//// string +//// > ): Map < +//// T1 , +//// Array < T3 > +//// > { throw new Error(); } +//// } +//// +//// interface IFoo< +//// T, +//// > { +//// new < T +//// > ( a: T); +//// op?< +//// T, +//// M +//// > (a: T, b : M ); +//// < +//// T, +//// >(x: T): T; +//// } +//// +//// type foo< +//// T +//// > = Foo < +//// number, Array < number > > ; +//// +//// function bar < +//// T, U extends T +//// > () { +//// return class < +//// T2, +//// > { +//// } +//// } +//// +//// bar< +//// string, +//// "s" +//// > (); +//// +//// declare const func: < +//// T extends number[], +//// > (x: T) => new < +//// U +//// > () => U; +//// +//// class A < T > extends bar < +//// T,number +//// >( ) < T +//// > { +//// } +//// +//// function s(x: TemplateStringsArray, ...args: any[]) { return x.join(); } +//// +//// const t = s< +//// number , +//// string[] & ArrayLike +//// >`abc${1}def` ; +//// + + +format.document(); + +verify.currentFileContentIs(` +class Foo< + T1 extends unknown, + T2 +> { + public method< + T3, + >(a: T1, b: Array< + string + >): Map< + T1, + Array + > { throw new Error(); } +} + +interface IFoo< + T, +> { + new (a: T); + op?< + T, + M + >(a: T, b: M); + < + T, + >(x: T): T; +} + +type foo< + T +> = Foo< + number, Array>; + +function bar< + T, U extends T +>() { + return class < + T2, + > { + } +} + +bar< + string, + "s" +>(); + +declare const func: < + T extends number[], +> (x: T) => new < + U +> () => U; + +class A extends bar< + T, number +>() { +} + +function s(x: TemplateStringsArray, ...args: any[]) { return x.join(); } + +const t = s< + number, + string[] & ArrayLike +>\`abc\${1}def\`; +`); From 75f4e95e8571305db0f66e637cf2818cb242d418 Mon Sep 17 00:00:00 2001 From: Harsheet Kakar <42893005+HarsheetKakar@users.noreply.github.com> Date: Wed, 1 Jun 2022 05:17:07 +0530 Subject: [PATCH 06/17] Fix46246 (#46357) * changed error message for interface extending primitive type * moved interface check to different function * changed part of interface declaration to is extended by interface Co-authored-by: harsheetkakar Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> --- src/compiler/checker.ts | 18 +++++++++++++++++- src/compiler/diagnosticMessages.json | 4 ++++ ...rorLocationForInterfaceExtension.errors.txt | 4 ++-- .../interfacedeclWithIndexerErrors.errors.txt | 15 ++++++++++++++- .../interfacedeclWithIndexerErrors.js | 7 +++++++ .../interfacedeclWithIndexerErrors.symbols | 17 ++++++++++++++--- .../interfacedeclWithIndexerErrors.types | 9 +++++++++ .../compiler/interfacedeclWithIndexerErrors.ts | 7 +++++++ 8 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8ae4c79370c..e5f226a37b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2478,7 +2478,12 @@ namespace ts { function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) { if (isPrimitiveTypeName(name)) { - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name)); + if (isExtendedByInterface(errorLocation)) { + error(errorLocation, Diagnostics.An_interface_cannot_extend_a_primitive_type_like_0_an_interface_can_only_extend_named_types_and_classes, unescapeLeadingUnderscores(name)); + } + else { + error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name)); + } return true; } const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); @@ -2499,6 +2504,17 @@ namespace ts { return false; } + function isExtendedByInterface(node: Node): boolean { + const grandparent = node.parent.parent; + const parentOfGrandparent = grandparent.parent; + if(grandparent && parentOfGrandparent){ + const isExtending = isHeritageClause(grandparent) && grandparent.token === SyntaxKind.ExtendsKeyword; + const isInterface = isInterfaceDeclaration(parentOfGrandparent); + return isExtending && isInterface; + } + return false; + } + function maybeMappedType(node: Node, symbol: Symbol) { const container = findAncestor(node.parent, n => isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0bf7b8b3eb5..05717148ebc 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3475,6 +3475,10 @@ "category": "Error", "code": 2839 }, + "An interface cannot extend a primitive type like '{0}'; an interface can only extend named types and classes": { + "category": "Error", + "code": 2840 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/errorLocationForInterfaceExtension.errors.txt b/tests/baselines/reference/errorLocationForInterfaceExtension.errors.txt index 6ed1517335d..24a6309e129 100644 --- a/tests/baselines/reference/errorLocationForInterfaceExtension.errors.txt +++ b/tests/baselines/reference/errorLocationForInterfaceExtension.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693: 'string' only refers to a type, but is being used as a value here. +tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes ==== tests/cases/compiler/errorLocationForInterfaceExtension.ts (1 errors) ==== @@ -6,5 +6,5 @@ tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693: interface x extends string { } ~~~~~~ -!!! error TS2693: 'string' only refers to a type, but is being used as a value here. +!!! error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes \ No newline at end of file diff --git a/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt b/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt index 2939a04948a..6aebe8a31f1 100644 --- a/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt +++ b/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt @@ -3,9 +3,11 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(14,5): error TS2411: Prop tests/cases/compiler/interfacedeclWithIndexerErrors.ts(15,5): error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. tests/cases/compiler/interfacedeclWithIndexerErrors.ts(19,5): error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to 'string' index type '() => string'. tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(44,21): error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(48,18): error TS2693: 'string' only refers to a type, but is being used as a value here. -==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (5 errors) ==== +==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (7 errors) ==== interface a0 { (): string; (a, b, c?: string): number; @@ -59,6 +61,17 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Prop interface d extends a { } + interface e extends number { + ~~~~~~ +!!! error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes + } + + interface f { + prop: typeof string; + ~~~~~~ +!!! error TS2693: 'string' only refers to a type, but is being used as a value here. + } + class c1 implements a { } var instance2 = new c1(); \ No newline at end of file diff --git a/tests/baselines/reference/interfacedeclWithIndexerErrors.js b/tests/baselines/reference/interfacedeclWithIndexerErrors.js index 776d43b940d..599ac30590a 100644 --- a/tests/baselines/reference/interfacedeclWithIndexerErrors.js +++ b/tests/baselines/reference/interfacedeclWithIndexerErrors.js @@ -42,6 +42,13 @@ interface c extends a, b { interface d extends a { } +interface e extends number { +} + +interface f { + prop: typeof string; +} + class c1 implements a { } var instance2 = new c1(); diff --git a/tests/baselines/reference/interfacedeclWithIndexerErrors.symbols b/tests/baselines/reference/interfacedeclWithIndexerErrors.symbols index 32880f2cb91..1ae6cf85950 100644 --- a/tests/baselines/reference/interfacedeclWithIndexerErrors.symbols +++ b/tests/baselines/reference/interfacedeclWithIndexerErrors.symbols @@ -84,11 +84,22 @@ interface d extends a { >a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1)) } +interface e extends number { +>e : Symbol(e, Decl(interfacedeclWithIndexerErrors.ts, 41, 1)) +} + +interface f { +>f : Symbol(f, Decl(interfacedeclWithIndexerErrors.ts, 44, 1)) + + prop: typeof string; +>prop : Symbol(f.prop, Decl(interfacedeclWithIndexerErrors.ts, 46, 13)) +} + class c1 implements a { ->c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1)) +>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1)) >a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1)) } var instance2 = new c1(); ->instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 45, 3)) ->c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1)) +>instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 52, 3)) +>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1)) diff --git a/tests/baselines/reference/interfacedeclWithIndexerErrors.types b/tests/baselines/reference/interfacedeclWithIndexerErrors.types index 67259ae88b8..a2f9964449d 100644 --- a/tests/baselines/reference/interfacedeclWithIndexerErrors.types +++ b/tests/baselines/reference/interfacedeclWithIndexerErrors.types @@ -70,6 +70,15 @@ interface c extends a, b { interface d extends a { } +interface e extends number { +} + +interface f { + prop: typeof string; +>prop : any +>string : any +} + class c1 implements a { >c1 : c1 } diff --git a/tests/cases/compiler/interfacedeclWithIndexerErrors.ts b/tests/cases/compiler/interfacedeclWithIndexerErrors.ts index 4b836247796..054d5e044ac 100644 --- a/tests/cases/compiler/interfacedeclWithIndexerErrors.ts +++ b/tests/cases/compiler/interfacedeclWithIndexerErrors.ts @@ -41,6 +41,13 @@ interface c extends a, b { interface d extends a { } +interface e extends number { +} + +interface f { + prop: typeof string; +} + class c1 implements a { } var instance2 = new c1(); \ No newline at end of file From 3cdb8081f7a66e32fc66ee41233b887d4adacb89 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 31 May 2022 17:05:33 -0700 Subject: [PATCH 07/17] Use NonNullable in more scenarios (#49330) * Remove getFalsyFlags and improve getNonNullableType * Apply getNonNullableType to left operand of || operator * Accept new baselines * Add tests --- src/compiler/checker.ts | 161 ++++++++---------- .../discriminatedUnionJsxElement.types | 4 +- tests/baselines/reference/mappedTypes4.types | 10 +- tests/baselines/reference/neverType.js | 2 +- tests/baselines/reference/neverType.types | 4 +- ...terExtendingStringAssignableToString.types | 2 +- .../baselines/reference/nonNullableTypes1.js | 85 +++++++++ .../reference/nonNullableTypes1.symbols | 89 ++++++++++ .../reference/nonNullableTypes1.types | 95 +++++++++++ .../nullishCoalescingOperator2.types | 4 +- .../nullishCoalescingOperator_es2020.types | 4 +- .../reference/privateIdentifierChain.1.types | 6 +- ...onalWithInteriorConditionalIsRelated.types | 2 +- tests/cases/compiler/nonNullableTypes1.ts | 37 ++++ 14 files changed, 395 insertions(+), 110 deletions(-) create mode 100644 tests/baselines/reference/nonNullableTypes1.js create mode 100644 tests/baselines/reference/nonNullableTypes1.symbols create mode 100644 tests/baselines/reference/nonNullableTypes1.types create mode 100644 tests/cases/compiler/nonNullableTypes1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e5f226a37b9..4fdc8b7f3f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -74,7 +74,7 @@ namespace ts { TypeofNEString = 1 << 8, // typeof x !== "string" TypeofNENumber = 1 << 9, // typeof x !== "number" TypeofNEBigInt = 1 << 10, // typeof x !== "bigint" - TypeofNEBoolean = 1 << 11, // typeof x !== "boolean" + TypeofNEBoolean = 1 << 11, // typeof x !== "boolean" TypeofNESymbol = 1 << 12, // typeof x !== "symbol" TypeofNEObject = 1 << 13, // typeof x !== "object" TypeofNEFunction = 1 << 14, // typeof x !== "function" @@ -87,7 +87,10 @@ namespace ts { NEUndefinedOrNull = 1 << 21, // x != undefined / x != null Truthy = 1 << 22, // x Falsy = 1 << 23, // !x - All = (1 << 24) - 1, + IsUndefined = 1 << 24, // Exactly undefined + IsNull = 1 << 25, // Exactly null + IsUndefinedOrNull = IsUndefined | IsNull, + All = (1 << 27) - 1, // The following members encode facts about particular kinds of types for use in the getTypeFacts function. // The presence of a particular fact means that the given test is true for some (and possibly all) values // of that kind of type. @@ -129,11 +132,13 @@ namespace ts { ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, - NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy, - EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull), + VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, + UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined, + NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull, + EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull), + EmptyObjectFacts = All & ~IsUndefinedOrNull, + UnknownFacts = All & ~IsUndefinedOrNull, AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined, - EmptyObjectFacts = All, // Masks OrFactsMask = TypeofEQFunction | TypeofNEObject, AndFactsMask = All & ~OrFactsMask, @@ -8903,7 +8908,7 @@ namespace ts { if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. - return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFlags.Undefined) ? getNonUndefinedType(type) : type; + return strictNullChecks && !(getTypeFacts(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFacts.IsUndefined) ? getNonUndefinedType(type) : type; } return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type), checkDeclarationInitializer(declaration, CheckMode.Normal)], UnionReduction.Subtype)); } @@ -18012,7 +18017,7 @@ namespace ts { const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType)); const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) && - (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); + (getTypeFacts(sourceType) & TypeFacts.IsUndefinedOrNull) === (getTypeFacts(targetType) & TypeFacts.IsUndefinedOrNull); let related = callbacks ? compareSignaturesRelated(targetSig, sourceSig, (checkMode & SignatureCheckMode.StrictArity) | (strictVariance ? SignatureCheckMode.StrictCallback : SignatureCheckMode.BivariantCallback), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) : !(checkMode & SignatureCheckMode.Callback) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); @@ -21380,31 +21385,8 @@ namespace ts { return value.base10Value === "0"; } - function getFalsyFlagsOfTypes(types: Type[]): TypeFlags { - let result: TypeFlags = 0; - for (const t of types) { - result |= getFalsyFlags(t); - } - return result; - } - - // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null - // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns - // no flags for all other types (including non-falsy literal types). - function getFalsyFlags(type: Type): TypeFlags { - const t = type.flags & TypeFlags.Intersection ? getBaseConstraintOrType(type) : type; - return t.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((t as UnionType).types) : - t.flags & TypeFlags.StringLiteral ? (t as StringLiteralType).value === "" ? TypeFlags.StringLiteral : 0 : - t.flags & TypeFlags.NumberLiteral ? (t as NumberLiteralType).value === 0 ? TypeFlags.NumberLiteral : 0 : - t.flags & TypeFlags.BigIntLiteral ? isZeroBigInt(t as BigIntLiteralType) ? TypeFlags.BigIntLiteral : 0 : - t.flags & TypeFlags.BooleanLiteral ? (t === falseType || t === regularFalseType) ? TypeFlags.BooleanLiteral : 0 : - t.flags & TypeFlags.PossiblyFalsy; - } - function removeDefinitelyFalsyTypes(type: Type): Type { - return getFalsyFlags(type) & TypeFlags.DefinitelyFalsy ? - filterType(type, t => !(getFalsyFlags(t) & TypeFlags.DefinitelyFalsy)) : - type; + return filterType(type, t => !!(getTypeFacts(t) & TypeFacts.Truthy)); } function extractDefinitelyFalsyTypes(type: Type): Type { @@ -21452,14 +21434,7 @@ namespace ts { } function getNonNullableType(type: Type): Type { - if (strictNullChecks) { - // First reduce away any constituents that are assignable to 'undefined' or 'null'. This not only eliminates - // 'undefined' and 'null', but also higher-order types such as a type parameter 'U extends undefined | null' - // that isn't eliminated by a NonNullable instantiation. - const reducedType = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); - return maybeTypeOfKind(reducedType, TypeFlags.Instantiable) ? getGlobalNonNullableTypeInstantiation(reducedType) : reducedType; - } - return type; + return strictNullChecks ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; } function addOptionalTypeMarker(type: Type) { @@ -23549,13 +23524,16 @@ namespace ts { resolved.members.get("bind" as __String) && isTypeSubtypeOf(type, globalFunctionType)); } - function getTypeFacts(type: Type, ignoreObjects = false): TypeFacts { + function getTypeFacts(type: Type): TypeFacts { + if (type.flags & (TypeFlags.Intersection | TypeFlags.Instantiable)) { + type = getBaseConstraintOfType(type) || unknownType; + } const flags = type.flags; - if (flags & TypeFlags.String) { + if (flags & (TypeFlags.String | TypeFlags.StringMapping)) { return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; } - if (flags & TypeFlags.StringLiteral) { - const isEmpty = (type as StringLiteralType).value === ""; + if (flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral)) { + const isEmpty = flags & TypeFlags.StringLiteral && (type as StringLiteralType).value === ""; return strictNullChecks ? isEmpty ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts : isEmpty ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts; @@ -23587,16 +23565,16 @@ namespace ts { (type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts; } if (flags & TypeFlags.Object) { - if (ignoreObjects) { - return TypeFacts.AndFactsMask; // This is the identity element for computing type facts of intersection. - } return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type as ObjectType) ? strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts : isFunctionObjectType(type as ObjectType) ? strictNullChecks ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts : strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } - if (flags & (TypeFlags.Void | TypeFlags.Undefined)) { + if (flags & TypeFlags.Void) { + return TypeFacts.VoidFacts; + } + if (flags & TypeFlags.Undefined) { return TypeFacts.UndefinedFacts; } if (flags & TypeFlags.Null) { @@ -23611,31 +23589,29 @@ namespace ts { if (flags & TypeFlags.Never) { return TypeFacts.None; } - if (flags & TypeFlags.Instantiable) { - return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType, ignoreObjects) : - strictNullChecks ? TypeFacts.NonEmptyStringStrictFacts : TypeFacts.NonEmptyStringFacts; - } if (flags & TypeFlags.Union) { - return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t, ignoreObjects), TypeFacts.None); + return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t), TypeFacts.None); } if (flags & TypeFlags.Intersection) { - // When an intersection contains a primitive type we ignore object type constituents as they are - // presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type. - ignoreObjects ||= maybeTypeOfKind(type, TypeFlags.Primitive); - return getIntersectionTypeFacts(type as IntersectionType, ignoreObjects); + return getIntersectionTypeFacts(type as IntersectionType); } - return TypeFacts.All; + return TypeFacts.UnknownFacts; } - function getIntersectionTypeFacts(type: IntersectionType, ignoreObjects: boolean): TypeFacts { + function getIntersectionTypeFacts(type: IntersectionType): TypeFacts { + // When an intersection contains a primitive type we ignore object type constituents as they are + // presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type. + const ignoreObjects = maybeTypeOfKind(type, TypeFlags.Primitive); // When computing the type facts of an intersection type, certain type facts are computed as `and` // and others are computed as `or`. let oredFacts = TypeFacts.None; let andedFacts = TypeFacts.All; for (const t of type.types) { - const f = getTypeFacts(t, ignoreObjects); - oredFacts |= f; - andedFacts &= f; + if (!(ignoreObjects && t.flags & TypeFlags.Object)) { + const f = getTypeFacts(t); + oredFacts |= f; + andedFacts &= f; + } } return oredFacts & TypeFacts.OrFactsMask | andedFacts & TypeFacts.AndFactsMask; } @@ -23644,7 +23620,10 @@ namespace ts { return filterType(type, t => (getTypeFacts(t) & include) !== 0); } - function getIntersectionWithFacts(type: Type, facts: TypeFacts) { + // This function is similar to getTypeWithFacts, except that in strictNullChecks mode it replaces type + // unknown with the union {} | null | undefined (and reduces that accordingly), and it intersects remaining + // instantiable types with {}, {} | null, or {} | undefined in order to remove null and/or undefined. + function getAdjustedTypeWithFacts(type: Type, facts: TypeFacts) { const reduced = recombineUnknownType(getTypeWithFacts(strictNullChecks && type.flags & TypeFlags.Unknown ? unknownUnionType : type, facts)); if (strictNullChecks) { switch (facts) { @@ -24903,10 +24882,10 @@ namespace ts { function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type { if (isMatchingReference(reference, expr)) { - return getIntersectionWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); + return getAdjustedTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); } if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) { - type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); } const access = getDiscriminantPropertyAccess(expr, type); if (access) { @@ -25052,7 +25031,7 @@ namespace ts { // Note that we include any and unknown in the exclusion test because their domain includes null and undefined. const removeNullable = equalsOperator !== assumeTrue && everyType(valueType, t => !!(t.flags & nullableFlags)) || equalsOperator === assumeTrue && everyType(valueType, t => !(t.flags & (TypeFlags.AnyOrUnknown | nullableFlags))); - return removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; + return removeNullable ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; } function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { @@ -25082,7 +25061,7 @@ namespace ts { valueType.flags & TypeFlags.Null ? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; - return getIntersectionWithFacts(type, facts); + return getAdjustedTypeWithFacts(type, facts); } if (assumeTrue) { const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? @@ -25104,7 +25083,7 @@ namespace ts { const target = getReferenceCandidate(typeOfExpr.expression); if (!isMatchingReference(reference, target)) { if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) { - return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); } return type; } @@ -25324,7 +25303,7 @@ namespace ts { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) { - return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); } return type; } @@ -25421,7 +25400,7 @@ namespace ts { } if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) && !(getTypeFacts(predicate.type) & TypeFacts.EQUndefined)) { - type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); } const access = getDiscriminantPropertyAccess(predicateArgument, type); if (access) { @@ -25480,7 +25459,7 @@ namespace ts { function narrowTypeByOptionality(type: Type, expr: Expression, assumePresent: boolean): Type { if (isMatchingReference(reference, expr)) { - return getTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull); + return getAdjustedTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull); } const access = getDiscriminantPropertyAccess(expr, type); if (access) { @@ -25572,8 +25551,8 @@ namespace ts { const annotationIncludesUndefined = strictNullChecks && declaration.kind === SyntaxKind.Parameter && declaration.initializer && - getFalsyFlags(declaredType) & TypeFlags.Undefined && - !(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined); + getTypeFacts(declaredType) & TypeFacts.IsUndefined && + !(getTypeFacts(checkExpression(declaration.initializer)) & TypeFacts.IsUndefined); popTypeResolution(); return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType; @@ -25930,7 +25909,7 @@ namespace ts { return convertAutoToAny(flowType); } } - else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { + else if (!assumeInitialized && !(getTypeFacts(type) & TypeFacts.IsUndefined) && getTypeFacts(flowType) & TypeFacts.IsUndefined) { error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; @@ -28907,23 +28886,23 @@ namespace ts { } function isNullableType(type: Type) { - return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable); + return !!(getTypeFacts(type) & TypeFacts.IsUndefinedOrNull); } function getNonNullableTypeIfNeeded(type: Type) { return isNullableType(type) ? getNonNullableType(type) : type; } - function reportObjectPossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) { - error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ? + function reportObjectPossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) { + error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ? Diagnostics.Object_is_possibly_null_or_undefined : Diagnostics.Object_is_possibly_undefined : Diagnostics.Object_is_possibly_null ); } - function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) { - error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ? + function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) { + error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ? Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined : Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined : Diagnostics.Cannot_invoke_an_object_which_is_possibly_null @@ -28933,15 +28912,15 @@ namespace ts { function checkNonNullTypeWithReporter( type: Type, node: Node, - reportError: (node: Node, kind: TypeFlags) => void + reportError: (node: Node, facts: TypeFacts) => void ): Type { if (strictNullChecks && type.flags & TypeFlags.Unknown) { error(node, Diagnostics.Object_is_of_type_unknown); return errorType; } - const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; - if (kind) { - reportError(node, kind); + const facts = getTypeFacts(type); + if (facts & TypeFacts.IsUndefinedOrNull) { + reportError(node, facts); const t = getNonNullableType(type); return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t; } @@ -29287,7 +29266,7 @@ namespace ts { assumeUninitialized = true; } const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType); - if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { + if (assumeUninitialized && !(getTypeFacts(propType) & TypeFacts.IsUndefined) && getTypeFacts(flowType) & TypeFacts.IsUndefined) { error(errorNode, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217 // Return the declared type to reduce follow-on errors return propType; @@ -33274,7 +33253,7 @@ namespace ts { const type = getTypeOfSymbol(symbol); if (strictNullChecks && !(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) && - !(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getFalsyFlags(type) & TypeFlags.Undefined)) { + !(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type) & TypeFacts.IsUndefined)) { error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional); } } @@ -33711,7 +33690,7 @@ namespace ts { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. if (strictNullChecks && - !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & TypeFlags.Undefined)) { + !(getTypeFacts(checkExpression(prop.objectAssignmentInitializer)) & TypeFacts.IsUndefined)) { sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); } checkBinaryLikeExpression(prop.name, prop.equalsToken!, prop.objectAssignmentInitializer, checkMode); @@ -34170,7 +34149,7 @@ namespace ts { case SyntaxKind.BarBarToken: case SyntaxKind.BarBarEqualsToken: { const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ? - getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) : + getUnionType([getNonNullableType(removeDefinitelyFalsyTypes(leftType)), rightType], UnionReduction.Subtype) : leftType; if (operator === SyntaxKind.BarBarEqualsToken) { checkAssignmentOperator(rightType); @@ -38125,7 +38104,7 @@ namespace ts { if (isModuleExportsAccessExpression(location)) return; const type = checkTruthinessExpression(location); const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression); - if (getFalsyFlags(type) || isPropertyExpressionCast) return; + if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return; // While it technically should be invalid for any known-truthy value // to be tested, we de-scope to functions and Promises unreferenced in @@ -40261,7 +40240,7 @@ namespace ts { const propName = (member as PropertyDeclaration).name; if (isIdentifier(propName) || isPrivateIdentifier(propName) || isComputedPropertyName(propName)) { const type = getTypeOfSymbol(getSymbolOfNode(member)); - if (!(type.flags & TypeFlags.AnyOrUnknown || getFalsyFlags(type) & TypeFlags.Undefined)) { + if (!(type.flags & TypeFlags.AnyOrUnknown || getTypeFacts(type) & TypeFacts.IsUndefined)) { if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) { error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName)); } @@ -40287,7 +40266,7 @@ namespace ts { setParent(reference, staticBlock); reference.flowNode = staticBlock.returnFlowNode; const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); - if (!(getFalsyFlags(flowType) & TypeFlags.Undefined)) { + if (!(getTypeFacts(flowType) & TypeFacts.IsUndefined)) { return true; } } @@ -40303,7 +40282,7 @@ namespace ts { setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); - return !(getFalsyFlags(flowType) & TypeFlags.Undefined); + return !(getTypeFacts(flowType) & TypeFacts.IsUndefined); } diff --git a/tests/baselines/reference/discriminatedUnionJsxElement.types b/tests/baselines/reference/discriminatedUnionJsxElement.types index 4f7b5a1ccdd..9057c9c55ab 100644 --- a/tests/baselines/reference/discriminatedUnionJsxElement.types +++ b/tests/baselines/reference/discriminatedUnionJsxElement.types @@ -14,8 +14,8 @@ function Menu >data : IData const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine; ->listItemVariant : ListItemVariant.OneLine | NonNullable ->data.menuItemsVariant ?? ListItemVariant.OneLine : ListItemVariant.OneLine | NonNullable +>listItemVariant : ListItemVariant.OneLine | MenuItemVariant +>data.menuItemsVariant ?? ListItemVariant.OneLine : ListItemVariant.OneLine | MenuItemVariant >data.menuItemsVariant : MenuItemVariant | undefined >data : IData >menuItemsVariant : MenuItemVariant | undefined diff --git a/tests/baselines/reference/mappedTypes4.types b/tests/baselines/reference/mappedTypes4.types index 434fcf1f7e8..f96bf1c5e8f 100644 --- a/tests/baselines/reference/mappedTypes4.types +++ b/tests/baselines/reference/mappedTypes4.types @@ -30,14 +30,14 @@ function boxify(obj: T): Boxified { >obj : (T & null) | (T & object) result[k] = { value: obj[k] }; ->result[k] = { value: obj[k] } : { value: NonNullable[Extract]; } +>result[k] = { value: obj[k] } : { value: (T & object)[Extract]; } >result[k] : Boxified[Extract] >result : Boxified >k : Extract ->{ value: obj[k] } : { value: NonNullable[Extract]; } ->value : NonNullable[Extract] ->obj[k] : NonNullable[Extract] ->obj : NonNullable +>{ value: obj[k] } : { value: (T & object)[Extract]; } +>value : (T & object)[Extract] +>obj[k] : (T & object)[Extract] +>obj : T & object >k : Extract } return result; diff --git a/tests/baselines/reference/neverType.js b/tests/baselines/reference/neverType.js index eb7ee331480..9d81d49d76a 100644 --- a/tests/baselines/reference/neverType.js +++ b/tests/baselines/reference/neverType.js @@ -180,7 +180,7 @@ declare function infiniteLoop1(): void; declare function infiniteLoop2(): never; declare function move1(direction: "up" | "down"): 1 | -1; declare function move2(direction: "up" | "down"): 1 | -1; -declare function check(x: T | undefined): T; +declare function check(x: T | undefined): NonNullable; declare class C { void1(): void; void2(): void; diff --git a/tests/baselines/reference/neverType.types b/tests/baselines/reference/neverType.types index 7ae38d11f76..b7e08eb503a 100644 --- a/tests/baselines/reference/neverType.types +++ b/tests/baselines/reference/neverType.types @@ -112,11 +112,11 @@ function move2(direction: "up" | "down") { } function check(x: T | undefined) { ->check : (x: T | undefined) => T +>check : (x: T | undefined) => NonNullable >x : T | undefined return x || error("Undefined value"); ->x || error("Undefined value") : T +>x || error("Undefined value") : NonNullable >x : T | undefined >error("Undefined value") : never >error : (message: string) => never diff --git a/tests/baselines/reference/nonNullParameterExtendingStringAssignableToString.types b/tests/baselines/reference/nonNullParameterExtendingStringAssignableToString.types index 5f9783c5f90..64c099cfa4e 100644 --- a/tests/baselines/reference/nonNullParameterExtendingStringAssignableToString.types +++ b/tests/baselines/reference/nonNullParameterExtendingStringAssignableToString.types @@ -25,7 +25,7 @@ function fn(one: T, two: U) { foo(two!); >foo(two!) : void >foo : (p: string) => void ->two! : NonNullable +>two! : U >two : U foo(three!); // this line is the important one diff --git a/tests/baselines/reference/nonNullableTypes1.js b/tests/baselines/reference/nonNullableTypes1.js new file mode 100644 index 00000000000..51d4918aa60 --- /dev/null +++ b/tests/baselines/reference/nonNullableTypes1.js @@ -0,0 +1,85 @@ +//// [nonNullableTypes1.ts] +function f1(x: T) { + let y = x || "hello"; // NonNullable | string +} + +function error(): never { + throw new Error(); +} + +function f2(x: T) { // NonNullable + return x || error(); +} + +function f3(x: unknown) { + let y = x!; // {} +} + +function f4(obj: T) { + if (obj?.x === "hello") { + obj; // NonNullable + } + if (obj?.x) { + obj; // NonNullable + } + if (typeof obj?.x === "string") { + obj; // NonNullable + } +} + +class A { + x = "hello"; + foo() { + let zz = this?.x; // string + } +} + + +//// [nonNullableTypes1.js] +"use strict"; +function f1(x) { + var y = x || "hello"; // NonNullable | string +} +function error() { + throw new Error(); +} +function f2(x) { + return x || error(); +} +function f3(x) { + var y = x; // {} +} +function f4(obj) { + if ((obj === null || obj === void 0 ? void 0 : obj.x) === "hello") { + obj; // NonNullable + } + if (obj === null || obj === void 0 ? void 0 : obj.x) { + obj; // NonNullable + } + if (typeof (obj === null || obj === void 0 ? void 0 : obj.x) === "string") { + obj; // NonNullable + } +} +var A = /** @class */ (function () { + function A() { + this.x = "hello"; + } + A.prototype.foo = function () { + var zz = this === null || this === void 0 ? void 0 : this.x; // string + }; + return A; +}()); + + +//// [nonNullableTypes1.d.ts] +declare function f1(x: T): void; +declare function error(): never; +declare function f2(x: T): NonNullable; +declare function f3(x: unknown): void; +declare function f4(obj: T): void; +declare class A { + x: string; + foo(): void; +} diff --git a/tests/baselines/reference/nonNullableTypes1.symbols b/tests/baselines/reference/nonNullableTypes1.symbols new file mode 100644 index 00000000000..7737d22f680 --- /dev/null +++ b/tests/baselines/reference/nonNullableTypes1.symbols @@ -0,0 +1,89 @@ +=== tests/cases/compiler/nonNullableTypes1.ts === +function f1(x: T) { +>f1 : Symbol(f1, Decl(nonNullableTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 0, 12)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 0, 15)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 0, 12)) + + let y = x || "hello"; // NonNullable | string +>y : Symbol(y, Decl(nonNullableTypes1.ts, 1, 7)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 0, 15)) +} + +function error(): never { +>error : Symbol(error, Decl(nonNullableTypes1.ts, 2, 1)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +function f2(x: T) { // NonNullable +>f2 : Symbol(f2, Decl(nonNullableTypes1.ts, 6, 1)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 8, 12)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 8, 15)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 8, 12)) + + return x || error(); +>x : Symbol(x, Decl(nonNullableTypes1.ts, 8, 15)) +>error : Symbol(error, Decl(nonNullableTypes1.ts, 2, 1)) +} + +function f3(x: unknown) { +>f3 : Symbol(f3, Decl(nonNullableTypes1.ts, 10, 1)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 12, 12)) + + let y = x!; // {} +>y : Symbol(y, Decl(nonNullableTypes1.ts, 13, 7)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 12, 12)) +} + +function f4(obj: T) { +>f4 : Symbol(f4, Decl(nonNullableTypes1.ts, 14, 1)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 16, 12)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) +>T : Symbol(T, Decl(nonNullableTypes1.ts, 16, 12)) + + if (obj?.x === "hello") { +>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) + + obj; // NonNullable +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) + } + if (obj?.x) { +>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) + + obj; // NonNullable +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) + } + if (typeof obj?.x === "string") { +>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) +>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23)) + + obj; // NonNullable +>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49)) + } +} + +class A { +>A : Symbol(A, Decl(nonNullableTypes1.ts, 26, 1)) + + x = "hello"; +>x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9)) + + foo() { +>foo : Symbol(A.foo, Decl(nonNullableTypes1.ts, 29, 16)) + + let zz = this?.x; // string +>zz : Symbol(zz, Decl(nonNullableTypes1.ts, 31, 11)) +>this?.x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9)) +>this : Symbol(A, Decl(nonNullableTypes1.ts, 26, 1)) +>x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9)) + } +} + diff --git a/tests/baselines/reference/nonNullableTypes1.types b/tests/baselines/reference/nonNullableTypes1.types new file mode 100644 index 00000000000..3d319114e79 --- /dev/null +++ b/tests/baselines/reference/nonNullableTypes1.types @@ -0,0 +1,95 @@ +=== tests/cases/compiler/nonNullableTypes1.ts === +function f1(x: T) { +>f1 : (x: T) => void +>x : T + + let y = x || "hello"; // NonNullable | string +>y : string | NonNullable +>x || "hello" : "hello" | NonNullable +>x : T +>"hello" : "hello" +} + +function error(): never { +>error : () => never + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +function f2(x: T) { // NonNullable +>f2 : (x: T) => NonNullable +>x : T + + return x || error(); +>x || error() : NonNullable +>x : T +>error() : never +>error : () => never +} + +function f3(x: unknown) { +>f3 : (x: unknown) => void +>x : unknown + + let y = x!; // {} +>y : {} +>x! : {} +>x : unknown +} + +function f4(obj: T) { +>f4 : (obj: T) => void +>x : string +>obj : T + + if (obj?.x === "hello") { +>obj?.x === "hello" : boolean +>obj?.x : string | undefined +>obj : { x: string; } | undefined +>x : string | undefined +>"hello" : "hello" + + obj; // NonNullable +>obj : NonNullable + } + if (obj?.x) { +>obj?.x : string | undefined +>obj : { x: string; } | undefined +>x : string | undefined + + obj; // NonNullable +>obj : NonNullable + } + if (typeof obj?.x === "string") { +>typeof obj?.x === "string" : boolean +>typeof obj?.x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>obj?.x : string | undefined +>obj : { x: string; } | undefined +>x : string | undefined +>"string" : "string" + + obj; // NonNullable +>obj : NonNullable + } +} + +class A { +>A : A + + x = "hello"; +>x : string +>"hello" : "hello" + + foo() { +>foo : () => void + + let zz = this?.x; // string +>zz : string +>this?.x : string +>this : this +>x : string + } +} + diff --git a/tests/baselines/reference/nullishCoalescingOperator2.types b/tests/baselines/reference/nullishCoalescingOperator2.types index dd1e31c4038..085b3de8d59 100644 --- a/tests/baselines/reference/nullishCoalescingOperator2.types +++ b/tests/baselines/reference/nullishCoalescingOperator2.types @@ -75,8 +75,8 @@ const aa6 = a6 ?? 'whatever' >'whatever' : "whatever" const aa7 = a7 ?? 'whatever' ->aa7 : unknown ->a7 ?? 'whatever' : unknown +>aa7 : {} +>a7 ?? 'whatever' : {} >a7 : unknown >'whatever' : "whatever" diff --git a/tests/baselines/reference/nullishCoalescingOperator_es2020.types b/tests/baselines/reference/nullishCoalescingOperator_es2020.types index 2dead6366b7..aec3adb3d46 100644 --- a/tests/baselines/reference/nullishCoalescingOperator_es2020.types +++ b/tests/baselines/reference/nullishCoalescingOperator_es2020.types @@ -75,8 +75,8 @@ const aa6 = a6 ?? 'whatever' >'whatever' : "whatever" const aa7 = a7 ?? 'whatever' ->aa7 : unknown ->a7 ?? 'whatever' : unknown +>aa7 : {} +>a7 ?? 'whatever' : {} >a7 : unknown >'whatever' : "whatever" diff --git a/tests/baselines/reference/privateIdentifierChain.1.types b/tests/baselines/reference/privateIdentifierChain.1.types index faf9a763c04..34deba67625 100644 --- a/tests/baselines/reference/privateIdentifierChain.1.types +++ b/tests/baselines/reference/privateIdentifierChain.1.types @@ -28,10 +28,10 @@ class A { this?.getA().#b; // Error >this?.getA().#b : A | undefined ->this?.getA() : A | undefined ->this?.getA : (() => A) | undefined +>this?.getA() : A +>this?.getA : () => A >this : this ->getA : (() => A) | undefined +>getA : () => A } } diff --git a/tests/baselines/reference/simplifyingConditionalWithInteriorConditionalIsRelated.types b/tests/baselines/reference/simplifyingConditionalWithInteriorConditionalIsRelated.types index 52e8ef8f14f..d9b814a2274 100644 --- a/tests/baselines/reference/simplifyingConditionalWithInteriorConditionalIsRelated.types +++ b/tests/baselines/reference/simplifyingConditionalWithInteriorConditionalIsRelated.types @@ -15,7 +15,7 @@ function JustConditional(): ConditionalType { >JustConditional : () => ConditionalType return ConditionalOrUndefined()!; // shouldn't error ->ConditionalOrUndefined()! : NonNullable> +>ConditionalOrUndefined()! : ConditionalType >ConditionalOrUndefined() : ConditionalType | undefined >ConditionalOrUndefined : () => ConditionalType | undefined } diff --git a/tests/cases/compiler/nonNullableTypes1.ts b/tests/cases/compiler/nonNullableTypes1.ts new file mode 100644 index 00000000000..7006c3c1fc6 --- /dev/null +++ b/tests/cases/compiler/nonNullableTypes1.ts @@ -0,0 +1,37 @@ +// @strict: true +// @declaration: true + +function f1(x: T) { + let y = x || "hello"; // NonNullable | string +} + +function error(): never { + throw new Error(); +} + +function f2(x: T) { // NonNullable + return x || error(); +} + +function f3(x: unknown) { + let y = x!; // {} +} + +function f4(obj: T) { + if (obj?.x === "hello") { + obj; // NonNullable + } + if (obj?.x) { + obj; // NonNullable + } + if (typeof obj?.x === "string") { + obj; // NonNullable + } +} + +class A { + x = "hello"; + foo() { + let zz = this?.x; // string + } +} From 9031497b92dddb712f0d057ccaa6bc82b9ae8e44 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 1 Jun 2022 06:10:42 +0000 Subject: [PATCH 08/17] Update package-lock.json --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a5f25690e79..57b28dc8df3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -234,7 +234,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -638,9 +638,9 @@ "dev": true }, "@types/node": { - "version": "17.0.36", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz", - "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==", + "version": "17.0.38", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz", + "integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==", "dev": true }, "@types/node-fetch": { @@ -4834,7 +4834,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-copy": { From 1beb1037c0b9db37e3bc0ca122bd5f2c13fadcfb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 1 Jun 2022 10:01:56 -0700 Subject: [PATCH 09/17] Fix check in isMappedTypeGenericIndexedAccess (#49341) * Fix check in isMappedTypeGenericIndexedAccess * Add regression tests --- src/compiler/checker.ts | 2 +- .../mappedTypeGenericIndexedAccess.js | 105 ++++++++++++ .../mappedTypeGenericIndexedAccess.symbols | 150 ++++++++++++++++++ .../mappedTypeGenericIndexedAccess.types | 147 +++++++++++++++++ .../mappedTypeGenericIndexedAccess.ts | 46 ++++++ 5 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/mappedTypeGenericIndexedAccess.js create mode 100644 tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols create mode 100644 tests/baselines/reference/mappedTypeGenericIndexedAccess.types create mode 100644 tests/cases/compiler/mappedTypeGenericIndexedAccess.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4fdc8b7f3f0..8188e14f5c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12308,7 +12308,7 @@ namespace ts { let objectType; return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped && !isGenericMappedType(objectType) && isGenericIndexType((type as IndexedAccessType).indexType) && - !(objectType as MappedType).declaration.questionToken && !(objectType as MappedType).declaration.nameType); + !(getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.ExcludeOptional) && !(objectType as MappedType).declaration.nameType); } /** diff --git a/tests/baselines/reference/mappedTypeGenericIndexedAccess.js b/tests/baselines/reference/mappedTypeGenericIndexedAccess.js new file mode 100644 index 00000000000..a06d9b27218 --- /dev/null +++ b/tests/baselines/reference/mappedTypeGenericIndexedAccess.js @@ -0,0 +1,105 @@ +//// [mappedTypeGenericIndexedAccess.ts] +// Repro from #49242 + +type Types = { + first: { a1: true }; + second: { a2: true }; + third: { a3: true }; +} + +class Test { + entries: { [T in keyof Types]?: Types[T][] }; + + constructor() { + this.entries = {}; + } + + addEntry(name: T, entry: Types[T]) { + if (!this.entries[name]) { + this.entries[name] = []; + } + this.entries[name]?.push(entry); + } +} + +// Repro from #49338 + +type TypesMap = { + [0]: { foo: 'bar'; }; + [1]: { a: 'b'; }; +}; + +type P = { t: T; } & TypesMap[T]; + +type TypeHandlers = { + [T in keyof TypesMap]?: (p: P) => void; +}; + +const typeHandlers: TypeHandlers = { + [0]: (p) => console.log(p.foo), + [1]: (p) => console.log(p.a), +}; + +const onSomeEvent = (p: P) => + typeHandlers[p.t]?.(p); + + +//// [mappedTypeGenericIndexedAccess.js] +"use strict"; +// Repro from #49242 +var _a; +var Test = /** @class */ (function () { + function Test() { + this.entries = {}; + } + Test.prototype.addEntry = function (name, entry) { + var _a; + if (!this.entries[name]) { + this.entries[name] = []; + } + (_a = this.entries[name]) === null || _a === void 0 ? void 0 : _a.push(entry); + }; + return Test; +}()); +var typeHandlers = (_a = {}, + _a[0] = function (p) { return console.log(p.foo); }, + _a[1] = function (p) { return console.log(p.a); }, + _a); +var onSomeEvent = function (p) { var _a; return (_a = typeHandlers[p.t]) === null || _a === void 0 ? void 0 : _a.call(typeHandlers, p); }; + + +//// [mappedTypeGenericIndexedAccess.d.ts] +declare type Types = { + first: { + a1: true; + }; + second: { + a2: true; + }; + third: { + a3: true; + }; +}; +declare class Test { + entries: { + [T in keyof Types]?: Types[T][]; + }; + constructor(); + addEntry(name: T, entry: Types[T]): void; +} +declare type TypesMap = { + [0]: { + foo: 'bar'; + }; + [1]: { + a: 'b'; + }; +}; +declare type P = { + t: T; +} & TypesMap[T]; +declare type TypeHandlers = { + [T in keyof TypesMap]?: (p: P) => void; +}; +declare const typeHandlers: TypeHandlers; +declare const onSomeEvent: (p: P) => void | undefined; diff --git a/tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols b/tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols new file mode 100644 index 00000000000..329932a9afd --- /dev/null +++ b/tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols @@ -0,0 +1,150 @@ +=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts === +// Repro from #49242 + +type Types = { +>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0)) + + first: { a1: true }; +>first : Symbol(first, Decl(mappedTypeGenericIndexedAccess.ts, 2, 14)) +>a1 : Symbol(a1, Decl(mappedTypeGenericIndexedAccess.ts, 3, 12)) + + second: { a2: true }; +>second : Symbol(second, Decl(mappedTypeGenericIndexedAccess.ts, 3, 24)) +>a2 : Symbol(a2, Decl(mappedTypeGenericIndexedAccess.ts, 4, 13)) + + third: { a3: true }; +>third : Symbol(third, Decl(mappedTypeGenericIndexedAccess.ts, 4, 25)) +>a3 : Symbol(a3, Decl(mappedTypeGenericIndexedAccess.ts, 5, 12)) +} + +class Test { +>Test : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1)) + + entries: { [T in keyof Types]?: Types[T][] }; +>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16)) +>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0)) +>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16)) + + constructor() { + this.entries = {}; +>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1)) +>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) + } + + addEntry(name: T, entry: Types[T]) { +>addEntry : Symbol(Test.addEntry, Decl(mappedTypeGenericIndexedAccess.ts, 13, 5)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13)) +>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0)) +>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13)) +>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44)) +>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13)) + + if (!this.entries[name]) { +>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1)) +>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36)) + + this.entries[name] = []; +>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1)) +>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36)) + } + this.entries[name]?.push(entry); +>this.entries[name]?.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1)) +>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12)) +>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44)) + } +} + +// Repro from #49338 + +type TypesMap = { +>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1)) + + [0]: { foo: 'bar'; }; +>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17)) +>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17)) +>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10)) + + [1]: { a: 'b'; }; +>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25)) +>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25)) +>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10)) + +}; + +type P = { t: T; } & TypesMap[T]; +>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7)) +>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1)) +>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7)) +>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7)) + +type TypeHandlers = { +>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59)) + + [T in keyof TypesMap]?: (p: P) => void; +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5)) +>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 33, 29)) +>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5)) + +}; + +const typeHandlers: TypeHandlers = { +>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5)) +>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59)) + + [0]: (p) => console.log(p.foo), +>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36)) +>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>p.foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10)) +>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10)) + + [1]: (p) => console.log(p.a), +>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35)) +>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>p.a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10)) +>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10)) + +}; + +const onSomeEvent = (p: P) => +>onSomeEvent : Symbol(onSomeEvent, Decl(mappedTypeGenericIndexedAccess.ts, 41, 5)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21)) +>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47)) +>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21)) + + typeHandlers[p.t]?.(p); +>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5)) +>p.t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47)) +>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36)) +>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47)) + diff --git a/tests/baselines/reference/mappedTypeGenericIndexedAccess.types b/tests/baselines/reference/mappedTypeGenericIndexedAccess.types new file mode 100644 index 00000000000..31effd4a6ce --- /dev/null +++ b/tests/baselines/reference/mappedTypeGenericIndexedAccess.types @@ -0,0 +1,147 @@ +=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts === +// Repro from #49242 + +type Types = { +>Types : { first: { a1: true;}; second: { a2: true;}; third: { a3: true;}; } + + first: { a1: true }; +>first : { a1: true; } +>a1 : true +>true : true + + second: { a2: true }; +>second : { a2: true; } +>a2 : true +>true : true + + third: { a3: true }; +>third : { a3: true; } +>a3 : true +>true : true +} + +class Test { +>Test : Test + + entries: { [T in keyof Types]?: Types[T][] }; +>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } + + constructor() { + this.entries = {}; +>this.entries = {} : {} +>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>this : this +>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>{} : {} + } + + addEntry(name: T, entry: Types[T]) { +>addEntry : (name: T, entry: Types[T]) => void +>name : T +>entry : Types[T] + + if (!this.entries[name]) { +>!this.entries[name] : boolean +>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T] +>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>this : this +>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>name : T + + this.entries[name] = []; +>this.entries[name] = [] : never[] +>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T] +>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>this : this +>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>name : T +>[] : never[] + } + this.entries[name]?.push(entry); +>this.entries[name]?.push(entry) : number | undefined +>this.entries[name]?.push : ((...items: Types[T][]) => number) | undefined +>this.entries[name] : Types[T][] | undefined +>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>this : this +>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; } +>name : T +>push : ((...items: Types[T][]) => number) | undefined +>entry : Types[T] + } +} + +// Repro from #49338 + +type TypesMap = { +>TypesMap : { 0: { foo: 'bar';}; 1: { a: 'b';}; } + + [0]: { foo: 'bar'; }; +>[0] : { foo: 'bar'; } +>0 : 0 +>foo : "bar" + + [1]: { a: 'b'; }; +>[1] : { a: 'b'; } +>1 : 1 +>a : "b" + +}; + +type P = { t: T; } & TypesMap[T]; +>P : P +>t : T + +type TypeHandlers = { +>TypeHandlers : { 0?: ((p: P<0>) => void) | undefined; 1?: ((p: P<1>) => void) | undefined; } + + [T in keyof TypesMap]?: (p: P) => void; +>p : P + +}; + +const typeHandlers: TypeHandlers = { +>typeHandlers : TypeHandlers +>{ [0]: (p) => console.log(p.foo), [1]: (p) => console.log(p.a),} : { 0: (p: P<0>) => void; 1: (p: P<1>) => void; } + + [0]: (p) => console.log(p.foo), +>[0] : (p: P<0>) => void +>0 : 0 +>(p) => console.log(p.foo) : (p: P<0>) => void +>p : P<0> +>console.log(p.foo) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>p.foo : "bar" +>p : P<0> +>foo : "bar" + + [1]: (p) => console.log(p.a), +>[1] : (p: P<1>) => void +>1 : 1 +>(p) => console.log(p.a) : (p: P<1>) => void +>p : P<1> +>console.log(p.a) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>p.a : "b" +>p : P<1> +>a : "b" + +}; + +const onSomeEvent = (p: P) => +>onSomeEvent : (p: P) => void | undefined +>(p: P) => typeHandlers[p.t]?.(p) : (p: P) => void | undefined +>p : P + + typeHandlers[p.t]?.(p); +>typeHandlers[p.t]?.(p) : void | undefined +>typeHandlers[p.t] : ((p: P) => void) | undefined +>typeHandlers : TypeHandlers +>p.t : T +>p : { t: T; } & ({ foo: "bar"; } | { a: "b"; }) +>t : T +>p : P + diff --git a/tests/cases/compiler/mappedTypeGenericIndexedAccess.ts b/tests/cases/compiler/mappedTypeGenericIndexedAccess.ts new file mode 100644 index 00000000000..68240b8bc87 --- /dev/null +++ b/tests/cases/compiler/mappedTypeGenericIndexedAccess.ts @@ -0,0 +1,46 @@ +// @strict: true +// @declaration: true + +// Repro from #49242 + +type Types = { + first: { a1: true }; + second: { a2: true }; + third: { a3: true }; +} + +class Test { + entries: { [T in keyof Types]?: Types[T][] }; + + constructor() { + this.entries = {}; + } + + addEntry(name: T, entry: Types[T]) { + if (!this.entries[name]) { + this.entries[name] = []; + } + this.entries[name]?.push(entry); + } +} + +// Repro from #49338 + +type TypesMap = { + [0]: { foo: 'bar'; }; + [1]: { a: 'b'; }; +}; + +type P = { t: T; } & TypesMap[T]; + +type TypeHandlers = { + [T in keyof TypesMap]?: (p: P) => void; +}; + +const typeHandlers: TypeHandlers = { + [0]: (p) => console.log(p.foo), + [1]: (p) => console.log(p.a), +}; + +const onSomeEvent = (p: P) => + typeHandlers[p.t]?.(p); From f3d57ccea8025335c5b93287828ab13f16593ee7 Mon Sep 17 00:00:00 2001 From: uhyo Date: Thu, 2 Jun 2022 07:34:37 +0900 Subject: [PATCH 10/17] Remove `undefined` from source type of renaming destructuring assignment with default (#41042) * Remove undefined from source type of destructuring assignment with renaming * add a test * add test case from original issue * add test with undefined default value * add more test cases with const declaration --- src/compiler/checker.ts | 4 + ...ructuringAssignmentWithDefault2.errors.txt | 42 ++++++ .../destructuringAssignmentWithDefault2.js | 46 +++++++ ...estructuringAssignmentWithDefault2.symbols | 84 ++++++++++++ .../destructuringAssignmentWithDefault2.types | 121 ++++++++++++++++++ .../destructuringAssignmentWithDefault2.ts | 27 ++++ 6 files changed, 324 insertions(+) create mode 100644 tests/baselines/reference/destructuringAssignmentWithDefault2.errors.txt create mode 100644 tests/baselines/reference/destructuringAssignmentWithDefault2.js create mode 100644 tests/baselines/reference/destructuringAssignmentWithDefault2.symbols create mode 100644 tests/baselines/reference/destructuringAssignmentWithDefault2.types create mode 100644 tests/cases/compiler/destructuringAssignmentWithDefault2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8188e14f5c8..62241eda9d8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33704,6 +33704,10 @@ namespace ts { if (target.kind === SyntaxKind.BinaryExpression && (target as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { checkBinaryExpression(target as BinaryExpression, checkMode); target = (target as BinaryExpression).left; + // A default value is specified, so remove undefined from the final type. + if (strictNullChecks) { + sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); + } } if (target.kind === SyntaxKind.ObjectLiteralExpression) { return checkObjectLiteralAssignment(target as ObjectLiteralExpression, sourceType, rightIsThis); diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault2.errors.txt b/tests/baselines/reference/destructuringAssignmentWithDefault2.errors.txt new file mode 100644 index 00000000000..b77bab849bd --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithDefault2.errors.txt @@ -0,0 +1,42 @@ +tests/cases/compiler/destructuringAssignmentWithDefault2.ts(11,4): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/destructuringAssignmentWithDefault2.ts(11,4): error TS2322: Type 'number | undefined' is not assignable to type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/destructuringAssignmentWithDefault2.ts(12,7): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/destructuringAssignmentWithDefault2.ts(13,7): error TS2322: Type 'undefined' is not assignable to type 'number'. + + +==== tests/cases/compiler/destructuringAssignmentWithDefault2.ts (4 errors) ==== + const a: { x?: number; y?: number } = { }; + + let x: number; + + // Should not error out + ({ x = 0 } = a); + ({ x: x = 0} = a); + ({ y: x = 0} = a); + + // Should be error + ({ x = undefined } = a); + ~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + ({ x: x = undefined } = a); + ~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + ({ y: x = undefined } = a); + ~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + + const { x: z1 } = a; + const { x: z2 = 0 } = a; + const { x: z3 = undefined } = a; + + + declare const r: Iterator; + let done: boolean; + let value; + + ({ done = false, value } = r.next()); + ({ done: done = false, value } = r.next()); \ No newline at end of file diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault2.js b/tests/baselines/reference/destructuringAssignmentWithDefault2.js new file mode 100644 index 00000000000..573dae6cceb --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithDefault2.js @@ -0,0 +1,46 @@ +//// [destructuringAssignmentWithDefault2.ts] +const a: { x?: number; y?: number } = { }; + +let x: number; + +// Should not error out +({ x = 0 } = a); +({ x: x = 0} = a); +({ y: x = 0} = a); + +// Should be error +({ x = undefined } = a); +({ x: x = undefined } = a); +({ y: x = undefined } = a); + +const { x: z1 } = a; +const { x: z2 = 0 } = a; +const { x: z3 = undefined } = a; + + +declare const r: Iterator; +let done: boolean; +let value; + +({ done = false, value } = r.next()); +({ done: done = false, value } = r.next()); + +//// [destructuringAssignmentWithDefault2.js] +var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; +var a = {}; +var x; +// Should not error out +(_a = a.x, x = _a === void 0 ? 0 : _a); +(_b = a.x, x = _b === void 0 ? 0 : _b); +(_c = a.y, x = _c === void 0 ? 0 : _c); +// Should be error +(_d = a.x, x = _d === void 0 ? undefined : _d); +(_e = a.x, x = _e === void 0 ? undefined : _e); +(_f = a.y, x = _f === void 0 ? undefined : _f); +var z1 = a.x; +var _l = a.x, z2 = _l === void 0 ? 0 : _l; +var _m = a.x, z3 = _m === void 0 ? undefined : _m; +var done; +var value; +(_g = r.next(), _h = _g.done, done = _h === void 0 ? false : _h, value = _g.value); +(_j = r.next(), _k = _j.done, done = _k === void 0 ? false : _k, value = _j.value); diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault2.symbols b/tests/baselines/reference/destructuringAssignmentWithDefault2.symbols new file mode 100644 index 00000000000..6a2e9186a6f --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithDefault2.symbols @@ -0,0 +1,84 @@ +=== tests/cases/compiler/destructuringAssignmentWithDefault2.ts === +const a: { x?: number; y?: number } = { }; +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 0, 10)) +>y : Symbol(y, Decl(destructuringAssignmentWithDefault2.ts, 0, 22)) + +let x: number; +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 2, 3)) + +// Should not error out +({ x = 0 } = a); +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 5, 2)) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +({ x: x = 0} = a); +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 6, 2)) +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 2, 3)) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +({ y: x = 0} = a); +>y : Symbol(y, Decl(destructuringAssignmentWithDefault2.ts, 7, 2)) +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 2, 3)) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +// Should be error +({ x = undefined } = a); +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 10, 2)) +>undefined : Symbol(undefined) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +({ x: x = undefined } = a); +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 11, 2)) +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 2, 3)) +>undefined : Symbol(undefined) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +({ y: x = undefined } = a); +>y : Symbol(y, Decl(destructuringAssignmentWithDefault2.ts, 12, 2)) +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 2, 3)) +>undefined : Symbol(undefined) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +const { x: z1 } = a; +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 0, 10)) +>z1 : Symbol(z1, Decl(destructuringAssignmentWithDefault2.ts, 14, 7)) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +const { x: z2 = 0 } = a; +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 0, 10)) +>z2 : Symbol(z2, Decl(destructuringAssignmentWithDefault2.ts, 15, 7)) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + +const { x: z3 = undefined } = a; +>x : Symbol(x, Decl(destructuringAssignmentWithDefault2.ts, 0, 10)) +>z3 : Symbol(z3, Decl(destructuringAssignmentWithDefault2.ts, 16, 7)) +>undefined : Symbol(undefined) +>a : Symbol(a, Decl(destructuringAssignmentWithDefault2.ts, 0, 5)) + + +declare const r: Iterator; +>r : Symbol(r, Decl(destructuringAssignmentWithDefault2.ts, 19, 13)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + +let done: boolean; +>done : Symbol(done, Decl(destructuringAssignmentWithDefault2.ts, 20, 3)) + +let value; +>value : Symbol(value, Decl(destructuringAssignmentWithDefault2.ts, 21, 3)) + +({ done = false, value } = r.next()); +>done : Symbol(done, Decl(destructuringAssignmentWithDefault2.ts, 23, 2)) +>value : Symbol(value, Decl(destructuringAssignmentWithDefault2.ts, 23, 16)) +>r.next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) +>r : Symbol(r, Decl(destructuringAssignmentWithDefault2.ts, 19, 13)) +>next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) + +({ done: done = false, value } = r.next()); +>done : Symbol(done, Decl(destructuringAssignmentWithDefault2.ts, 24, 2)) +>done : Symbol(done, Decl(destructuringAssignmentWithDefault2.ts, 20, 3)) +>value : Symbol(value, Decl(destructuringAssignmentWithDefault2.ts, 24, 22)) +>r.next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) +>r : Symbol(r, Decl(destructuringAssignmentWithDefault2.ts, 19, 13)) +>next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) + diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault2.types b/tests/baselines/reference/destructuringAssignmentWithDefault2.types new file mode 100644 index 00000000000..9acf42f3a1b --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithDefault2.types @@ -0,0 +1,121 @@ +=== tests/cases/compiler/destructuringAssignmentWithDefault2.ts === +const a: { x?: number; y?: number } = { }; +>a : { x?: number | undefined; y?: number | undefined; } +>x : number | undefined +>y : number | undefined +>{ } : {} + +let x: number; +>x : number + +// Should not error out +({ x = 0 } = a); +>({ x = 0 } = a) : { x?: number | undefined; y?: number | undefined; } +>{ x = 0 } = a : { x?: number | undefined; y?: number | undefined; } +>{ x = 0 } : { x?: number; } +>x : number +>0 : 0 +>a : { x?: number | undefined; y?: number | undefined; } + +({ x: x = 0} = a); +>({ x: x = 0} = a) : { x?: number | undefined; y?: number | undefined; } +>{ x: x = 0} = a : { x?: number | undefined; y?: number | undefined; } +>{ x: x = 0} : { x?: number; } +>x : number +>x = 0 : 0 +>x : number +>0 : 0 +>a : { x?: number | undefined; y?: number | undefined; } + +({ y: x = 0} = a); +>({ y: x = 0} = a) : { x?: number | undefined; y?: number | undefined; } +>{ y: x = 0} = a : { x?: number | undefined; y?: number | undefined; } +>{ y: x = 0} : { y?: number; } +>y : number +>x = 0 : 0 +>x : number +>0 : 0 +>a : { x?: number | undefined; y?: number | undefined; } + +// Should be error +({ x = undefined } = a); +>({ x = undefined } = a) : { x?: number | undefined; y?: number | undefined; } +>{ x = undefined } = a : { x?: number | undefined; y?: number | undefined; } +>{ x = undefined } : { x?: number; } +>x : number +>undefined : undefined +>a : { x?: number | undefined; y?: number | undefined; } + +({ x: x = undefined } = a); +>({ x: x = undefined } = a) : { x?: number | undefined; y?: number | undefined; } +>{ x: x = undefined } = a : { x?: number | undefined; y?: number | undefined; } +>{ x: x = undefined } : { x?: undefined; } +>x : undefined +>x = undefined : undefined +>x : number +>undefined : undefined +>a : { x?: number | undefined; y?: number | undefined; } + +({ y: x = undefined } = a); +>({ y: x = undefined } = a) : { x?: number | undefined; y?: number | undefined; } +>{ y: x = undefined } = a : { x?: number | undefined; y?: number | undefined; } +>{ y: x = undefined } : { y?: undefined; } +>y : undefined +>x = undefined : undefined +>x : number +>undefined : undefined +>a : { x?: number | undefined; y?: number | undefined; } + +const { x: z1 } = a; +>x : any +>z1 : number | undefined +>a : { x?: number | undefined; y?: number | undefined; } + +const { x: z2 = 0 } = a; +>x : any +>z2 : number +>0 : 0 +>a : { x?: number | undefined; y?: number | undefined; } + +const { x: z3 = undefined } = a; +>x : any +>z3 : number | undefined +>undefined : undefined +>a : { x?: number | undefined; y?: number | undefined; } + + +declare const r: Iterator; +>r : Iterator + +let done: boolean; +>done : boolean + +let value; +>value : any + +({ done = false, value } = r.next()); +>({ done = false, value } = r.next()) : IteratorResult +>{ done = false, value } = r.next() : IteratorResult +>{ done = false, value } : { done?: boolean; value: any; } +>done : boolean +>false : false +>value : any +>r.next() : IteratorResult +>r.next : (...args: [] | [undefined]) => IteratorResult +>r : Iterator +>next : (...args: [] | [undefined]) => IteratorResult + +({ done: done = false, value } = r.next()); +>({ done: done = false, value } = r.next()) : IteratorResult +>{ done: done = false, value } = r.next() : IteratorResult +>{ done: done = false, value } : { done?: boolean; value: any; } +>done : boolean +>done = false : false +>done : boolean +>false : false +>value : any +>r.next() : IteratorResult +>r.next : (...args: [] | [undefined]) => IteratorResult +>r : Iterator +>next : (...args: [] | [undefined]) => IteratorResult + diff --git a/tests/cases/compiler/destructuringAssignmentWithDefault2.ts b/tests/cases/compiler/destructuringAssignmentWithDefault2.ts new file mode 100644 index 00000000000..8dc6fd0a464 --- /dev/null +++ b/tests/cases/compiler/destructuringAssignmentWithDefault2.ts @@ -0,0 +1,27 @@ +// @lib: es2015 +// @strictNullChecks: true +const a: { x?: number; y?: number } = { }; + +let x: number; + +// Should not error out +({ x = 0 } = a); +({ x: x = 0} = a); +({ y: x = 0} = a); + +// Should be error +({ x = undefined } = a); +({ x: x = undefined } = a); +({ y: x = undefined } = a); + +const { x: z1 } = a; +const { x: z2 = 0 } = a; +const { x: z3 = undefined } = a; + + +declare const r: Iterator; +let done: boolean; +let value; + +({ done = false, value } = r.next()); +({ done: done = false, value } = r.next()); \ No newline at end of file From ce9b4c1d5b612895f45c2488d8ba7279b4323be8 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Thu, 2 Jun 2022 06:06:32 +0000 Subject: [PATCH 11/17] Update package-lock.json --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57b28dc8df3..09b9f2b7a27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5157,7 +5157,7 @@ "plugin-error": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==", "dev": true, "requires": { "ansi-cyan": "^0.1.1", @@ -5291,7 +5291,7 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, "qs": { From c6447f94546bed0205e802e22e9cc235cb5213a0 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 3 Jun 2022 00:07:03 +0300 Subject: [PATCH 12/17] fix(49306): add isImportTypeAssertionContainer helper (#49313) --- src/compiler/factory/nodeTests.ts | 4 ++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 3 files changed, 6 insertions(+) diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts index cf473caf65b..d4ae3767cf0 100644 --- a/src/compiler/factory/nodeTests.ts +++ b/src/compiler/factory/nodeTests.ts @@ -597,6 +597,10 @@ namespace ts { return node.kind === SyntaxKind.ImportClause; } + export function isImportTypeAssertionContainer(node: Node): node is ImportTypeAssertionContainer { + return node.kind === SyntaxKind.ImportTypeAssertionContainer; + } + export function isAssertClause(node: Node): node is AssertClause { return node.kind === SyntaxKind.AssertClause; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ab7ae0cde49..25b43264785 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4724,6 +4724,7 @@ declare namespace ts { function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration; function isImportDeclaration(node: Node): node is ImportDeclaration; function isImportClause(node: Node): node is ImportClause; + function isImportTypeAssertionContainer(node: Node): node is ImportTypeAssertionContainer; function isAssertClause(node: Node): node is AssertClause; function isAssertEntry(node: Node): node is AssertEntry; function isNamespaceImport(node: Node): node is NamespaceImport; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 658786b63f1..1012dbe8bf8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4724,6 +4724,7 @@ declare namespace ts { function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration; function isImportDeclaration(node: Node): node is ImportDeclaration; function isImportClause(node: Node): node is ImportClause; + function isImportTypeAssertionContainer(node: Node): node is ImportTypeAssertionContainer; function isAssertClause(node: Node): node is AssertClause; function isAssertEntry(node: Node): node is AssertEntry; function isNamespaceImport(node: Node): node is NamespaceImport; From 2cb8ee27f0acffdcdbb4aa02a1d8f096720c5e87 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 3 Jun 2022 00:21:36 +0300 Subject: [PATCH 13/17] fix(48653): throw an error on an invalid optional chain from new expression (#48656) --- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/parser.ts | 3 +++ ...dOptionalChainFromNewExpression.errors.txt | 13 +++++++++++ .../invalidOptionalChainFromNewExpression.js | 19 ++++++++++++++++ ...alidOptionalChainFromNewExpression.symbols | 18 +++++++++++++++ ...nvalidOptionalChainFromNewExpression.types | 22 +++++++++++++++++++ .../invalidOptionalChainFromNewExpression.ts | 6 +++++ 7 files changed, 85 insertions(+) create mode 100644 tests/baselines/reference/invalidOptionalChainFromNewExpression.errors.txt create mode 100644 tests/baselines/reference/invalidOptionalChainFromNewExpression.js create mode 100644 tests/baselines/reference/invalidOptionalChainFromNewExpression.symbols create mode 100644 tests/baselines/reference/invalidOptionalChainFromNewExpression.types create mode 100644 tests/cases/compiler/invalidOptionalChainFromNewExpression.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 05717148ebc..51e4a59cca2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -651,6 +651,10 @@ "category": "Error", "code": 1208 }, + "Invalid optional chain from new expression. Did you mean to call '{0}()'?": { + "category": "Error", + "code": 1209 + }, "Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of '{0}'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode.": { "category": "Error", "code": 1210 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1b502dfc22f..b44b86e971a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5942,6 +5942,9 @@ namespace ts { typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; expression = (expression as ExpressionWithTypeArguments).expression; } + if (token() === SyntaxKind.QuestionDotToken) { + parseErrorAtCurrentToken(Diagnostics.Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0, getTextOfNodeFromSourceText(sourceText, expression)); + } const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; return finishNode(factory.createNewExpression(expression, typeArguments, argumentList), pos); } diff --git a/tests/baselines/reference/invalidOptionalChainFromNewExpression.errors.txt b/tests/baselines/reference/invalidOptionalChainFromNewExpression.errors.txt new file mode 100644 index 00000000000..c9ecc87fdc0 --- /dev/null +++ b/tests/baselines/reference/invalidOptionalChainFromNewExpression.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/invalidOptionalChainFromNewExpression.ts(5,6): error TS1209: Invalid optional chain from new expression. Did you mean to call 'A()'? + + +==== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts (1 errors) ==== + class A { + b() {} + } + + new A?.b() // error + ~~ +!!! error TS1209: Invalid optional chain from new expression. Did you mean to call 'A()'? + new A()?.b() // ok + \ No newline at end of file diff --git a/tests/baselines/reference/invalidOptionalChainFromNewExpression.js b/tests/baselines/reference/invalidOptionalChainFromNewExpression.js new file mode 100644 index 00000000000..39a235554c7 --- /dev/null +++ b/tests/baselines/reference/invalidOptionalChainFromNewExpression.js @@ -0,0 +1,19 @@ +//// [invalidOptionalChainFromNewExpression.ts] +class A { + b() {} +} + +new A?.b() // error +new A()?.b() // ok + + +//// [invalidOptionalChainFromNewExpression.js] +var _a, _b; +var A = /** @class */ (function () { + function A() { + } + A.prototype.b = function () { }; + return A; +}()); +(_a = new A) === null || _a === void 0 ? void 0 : _a.b(); // error +(_b = new A()) === null || _b === void 0 ? void 0 : _b.b(); // ok diff --git a/tests/baselines/reference/invalidOptionalChainFromNewExpression.symbols b/tests/baselines/reference/invalidOptionalChainFromNewExpression.symbols new file mode 100644 index 00000000000..b251cceab37 --- /dev/null +++ b/tests/baselines/reference/invalidOptionalChainFromNewExpression.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts === +class A { +>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0)) + + b() {} +>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9)) +} + +new A?.b() // error +>new A?.b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9)) +>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0)) +>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9)) + +new A()?.b() // ok +>new A()?.b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9)) +>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0)) +>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9)) + diff --git a/tests/baselines/reference/invalidOptionalChainFromNewExpression.types b/tests/baselines/reference/invalidOptionalChainFromNewExpression.types new file mode 100644 index 00000000000..abe2da88392 --- /dev/null +++ b/tests/baselines/reference/invalidOptionalChainFromNewExpression.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts === +class A { +>A : A + + b() {} +>b : () => void +} + +new A?.b() // error +>new A?.b() : void +>new A?.b : () => void +>new A : A +>A : typeof A +>b : () => void + +new A()?.b() // ok +>new A()?.b() : void +>new A()?.b : () => void +>new A() : A +>A : typeof A +>b : () => void + diff --git a/tests/cases/compiler/invalidOptionalChainFromNewExpression.ts b/tests/cases/compiler/invalidOptionalChainFromNewExpression.ts new file mode 100644 index 00000000000..e47512775e0 --- /dev/null +++ b/tests/cases/compiler/invalidOptionalChainFromNewExpression.ts @@ -0,0 +1,6 @@ +class A { + b() {} +} + +new A?.b() // error +new A()?.b() // ok From 19b22844d8f08accd190dfcbbb74e0cab2224078 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 2 Jun 2022 15:43:26 -0700 Subject: [PATCH 14/17] Use node's algorithm for calculating the longest matching export/import pattern (#49361) --- src/compiler/moduleNameResolver.ts | 20 +- ...rnExportsExclude(module=node16).errors.txt | 123 +++++++++ ...agePatternExportsExclude(module=node16).js | 127 ++++++++++ ...tternExportsExclude(module=node16).symbols | 120 +++++++++ ...PatternExportsExclude(module=node16).types | 120 +++++++++ ...ExportsExclude(module=nodenext).errors.txt | 123 +++++++++ ...ePatternExportsExclude(module=nodenext).js | 127 ++++++++++ ...ernExportsExclude(module=nodenext).symbols | 120 +++++++++ ...tternExportsExclude(module=nodenext).types | 120 +++++++++ ...rnExportsExclude(module=node16).errors.txt | 177 +++++++++++++ ...agePatternExportsExclude(module=node16).js | 187 ++++++++++++++ ...tternExportsExclude(module=node16).symbols | 234 ++++++++++++++++++ ...PatternExportsExclude(module=node16).types | 234 ++++++++++++++++++ ...ExportsExclude(module=nodenext).errors.txt | 177 +++++++++++++ ...ePatternExportsExclude(module=nodenext).js | 187 ++++++++++++++ ...ernExportsExclude(module=nodenext).symbols | 234 ++++++++++++++++++ ...tternExportsExclude(module=nodenext).types | 234 ++++++++++++++++++ ...ulesAllowJsPackagePatternExportsExclude.ts | 72 ++++++ ...nodeModulesPackagePatternExportsExclude.ts | 112 +++++++++ 19 files changed, 2847 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).types create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts create mode 100644 tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index fc62e3ee01b..63aadea575a 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2064,6 +2064,24 @@ namespace ts { return toSearchResult(/*value*/ undefined); } + /** + * From https://github.com/nodejs/node/blob/8f39f51cbbd3b2de14b9ee896e26421cc5b20121/lib/internal/modules/esm/resolve.js#L722 - + * "longest" has some nuance as to what "longest" means in the presence of pattern trailers + */ + function comparePatternKeys(a: string, b: string) { + const aPatternIndex = a.indexOf("*"); + const bPatternIndex = b.indexOf("*"); + const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; + const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; + if (baseLenA > baseLenB) return -1; + if (baseLenB > baseLenA) return 1; + if (aPatternIndex === -1) return 1; + if (bPatternIndex === -1) return -1; + if (a.length > b.length) return -1; + if (b.length > a.length) return 1; + return 0; + } + function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult | undefined { const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, moduleName, scope, isImports); @@ -2071,7 +2089,7 @@ namespace ts { const target = (lookupTable as {[idx: string]: unknown})[moduleName]; return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false); } - const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike), k => k.indexOf("*") !== -1 || endsWith(k, "/")), (a, b) => a.length - b.length); + const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike), k => k.indexOf("*") !== -1 || endsWith(k, "/")), comparePatternKeys); for (const potentialTarget of expandingKeys) { if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) { const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).errors.txt b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).errors.txt new file mode 100644 index 00000000000..d47318a006c --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).errors.txt @@ -0,0 +1,123 @@ +tests/cases/conformance/node/allowJs/index.cjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.cjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.cjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + + +==== tests/cases/conformance/node/allowJs/index.js (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/index.mjs (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/index.cjs (3 errors) ==== + // cjs format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts (3 errors) ==== + // esm format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/package.json (0 errors) ==== + { + "name": "package", + "private": true, + "type": "module" + } +==== tests/cases/conformance/node/allowJs/node_modules/inner/package.json (0 errors) ==== + { + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).js b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).js new file mode 100644 index 00000000000..7ede2700377 --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).js @@ -0,0 +1,127 @@ +//// [tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts] //// + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.cjs] +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [package.json] +{ + "name": "package", + "private": true, + "type": "module" +} +//// [package.json] +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.cjs] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// cjs format file +const cjsi = __importStar(require("inner/cjs/exclude/index")); +const mjsi = __importStar(require("inner/mjs/exclude/index")); +const typei = __importStar(require("inner/js/exclude/index")); +cjsi; +mjsi; +typei; + + +//// [index.d.ts] +export {}; +//// [index.d.mts] +export {}; +//// [index.d.cts] +export {}; diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).symbols b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).symbols new file mode 100644 index 00000000000..ba8ceb18ddf --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).symbols @@ -0,0 +1,120 @@ +=== tests/cases/conformance/node/allowJs/index.js === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.js, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.js, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.js, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.js, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.js, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.js, 3, 6)) + +=== tests/cases/conformance/node/allowJs/index.mjs === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.mjs, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.mjs, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.mjs, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.mjs, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.mjs, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.mjs, 3, 6)) + +=== tests/cases/conformance/node/allowJs/index.cjs === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.cjs, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.cjs, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.cjs, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.cjs, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.cjs, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.cjs, 3, 6)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.cts, 6, 8)) + diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).types b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).types new file mode 100644 index 00000000000..85c53a5460d --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=node16).types @@ -0,0 +1,120 @@ +=== tests/cases/conformance/node/allowJs/index.js === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/index.mjs === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/index.cjs === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).errors.txt b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).errors.txt new file mode 100644 index 00000000000..d47318a006c --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).errors.txt @@ -0,0 +1,123 @@ +tests/cases/conformance/node/allowJs/index.cjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.cjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.cjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.js(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/index.mjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + + +==== tests/cases/conformance/node/allowJs/index.js (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/index.mjs (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/index.cjs (3 errors) ==== + // cjs format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts (3 errors) ==== + // esm format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/allowJs/package.json (0 errors) ==== + { + "name": "package", + "private": true, + "type": "module" + } +==== tests/cases/conformance/node/allowJs/node_modules/inner/package.json (0 errors) ==== + { + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).js b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).js new file mode 100644 index 00000000000..7ede2700377 --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).js @@ -0,0 +1,127 @@ +//// [tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts] //// + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.cjs] +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [package.json] +{ + "name": "package", + "private": true, + "type": "module" +} +//// [package.json] +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +//// [index.cjs] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// cjs format file +const cjsi = __importStar(require("inner/cjs/exclude/index")); +const mjsi = __importStar(require("inner/mjs/exclude/index")); +const typei = __importStar(require("inner/js/exclude/index")); +cjsi; +mjsi; +typei; + + +//// [index.d.ts] +export {}; +//// [index.d.mts] +export {}; +//// [index.d.cts] +export {}; diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).symbols b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).symbols new file mode 100644 index 00000000000..ba8ceb18ddf --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).symbols @@ -0,0 +1,120 @@ +=== tests/cases/conformance/node/allowJs/index.js === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.js, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.js, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.js, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.js, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.js, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.js, 3, 6)) + +=== tests/cases/conformance/node/allowJs/index.mjs === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.mjs, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.mjs, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.mjs, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.mjs, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.mjs, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.mjs, 3, 6)) + +=== tests/cases/conformance/node/allowJs/index.cjs === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.cjs, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.cjs, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.cjs, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.cjs, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.cjs, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.cjs, 3, 6)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.cts, 6, 8)) + diff --git a/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).types b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).types new file mode 100644 index 00000000000..85c53a5460d --- /dev/null +++ b/tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsExclude(module=nodenext).types @@ -0,0 +1,120 @@ +=== tests/cases/conformance/node/allowJs/index.js === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/index.mjs === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/index.cjs === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).errors.txt b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).errors.txt new file mode 100644 index 00000000000..863b455cf47 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).errors.txt @@ -0,0 +1,177 @@ +tests/cases/conformance/node/index.cts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(9,24): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. +tests/cases/conformance/node/index.mts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.mts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.mts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/index.d.cts(3,22): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. +tests/cases/conformance/node/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'. +tests/cases/conformance/node/node_modules/inner/index.d.ts(3,22): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + + +==== tests/cases/conformance/node/index.ts (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/index.mts (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/index.cts (4 errors) ==== + // cjs format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts (3 errors) ==== + // esm format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.ts (2 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/index"; + ~~~ +!!! error TS2303: Circular definition of import alias 'cjs'. + import * as mjs from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.mts (0 errors) ==== + // esm format file + import * as cjs from "inner/cjs/index"; + import * as mjs from "inner/mjs/index"; + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.cts (1 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/index"; + import * as mjs from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/package.json (0 errors) ==== + { + "name": "package", + "private": true, + "type": "module" + } +==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ==== + { + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).js b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).js new file mode 100644 index 00000000000..5c3a1fea219 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).js @@ -0,0 +1,187 @@ +//// [tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts] //// + +//// [index.ts] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.mts] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.cts] +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [package.json] +{ + "name": "package", + "private": true, + "type": "module" +} +//// [package.json] +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.cjs] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// cjs format file +const cjsi = __importStar(require("inner/cjs/exclude/index")); +const mjsi = __importStar(require("inner/mjs/exclude/index")); +const typei = __importStar(require("inner/js/exclude/index")); +cjsi; +mjsi; +typei; +const cjsi2 = __importStar(require("inner/cjs/index")); +const mjsi2 = __importStar(require("inner/mjs/index")); +const typei2 = __importStar(require("inner/js/index")); +cjsi2; +mjsi2; +typei2; + + +//// [index.d.ts] +export {}; +//// [index.d.mts] +export {}; +//// [index.d.cts] +export {}; diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).symbols b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).symbols new file mode 100644 index 00000000000..6114f146f23 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).symbols @@ -0,0 +1,234 @@ +=== tests/cases/conformance/node/index.ts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.ts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.ts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.ts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.ts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.ts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.ts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.ts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.ts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.ts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.ts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.ts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.ts, 9, 6)) + +=== tests/cases/conformance/node/index.mts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.mts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.mts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.mts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.mts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.mts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.mts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.mts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.mts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.mts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.mts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.mts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.mts, 9, 6)) + +=== tests/cases/conformance/node/index.cts === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.cts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.cts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.cts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.cts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.cts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.cts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.cts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.cts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.cts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.cts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.cts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.cts, 9, 6)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.cts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(mjs.cjs.cjs.type.cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs.cjs.cjs.type.mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(mjs.cjs.cjs.type.type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs.cjs.mjs.cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(cjs.cjs.mjs.mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(cjs.cjs.mjs.type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs.cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(cjs.mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(cjs.type, Decl(index.d.cts, 6, 8)) + diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).types b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).types new file mode 100644 index 00000000000..517f6dfa99b --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=node16).types @@ -0,0 +1,234 @@ +=== tests/cases/conformance/node/index.ts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.cjs.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof typei2 + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.cjs.mjs + +typei2; +>typei2 : typeof typei2 + +=== tests/cases/conformance/node/index.mts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.cjs.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof typei2 + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.cjs.mjs + +typei2; +>typei2 : typeof typei2 + +=== tests/cases/conformance/node/index.cts === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof cjsi2.mjs.cjs.type + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.mjs + +typei2; +>typei2 : typeof cjsi2.mjs.cjs.type + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : any + +import * as mjs from "inner/mjs/index"; +>mjs : typeof mjs + +import * as type from "inner/js/index"; +>type : typeof mjs.cjs.cjs.type + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : typeof mjs + +export { type }; +>type : typeof mjs.cjs.cjs.type + +=== tests/cases/conformance/node/node_modules/inner/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/index"; +>cjs : typeof cjs + +import * as mjs from "inner/mjs/index"; +>mjs : typeof cjs.cjs.mjs + +import * as type from "inner/js/index"; +>type : typeof cjs.cjs.mjs.type + +export { cjs }; +>cjs : typeof cjs + +export { mjs }; +>mjs : typeof cjs.cjs.mjs + +export { type }; +>type : typeof cjs.cjs.mjs.type + +=== tests/cases/conformance/node/node_modules/inner/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : typeof cjs + +import * as mjs from "inner/mjs/index"; +>mjs : typeof cjs.mjs + +import * as type from "inner/js/index"; +>type : typeof cjs.mjs.cjs.type + +export { cjs }; +>cjs : typeof cjs + +export { mjs }; +>mjs : typeof cjs.mjs + +export { type }; +>type : typeof cjs.mjs.cjs.type + diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).errors.txt b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).errors.txt new file mode 100644 index 00000000000..863b455cf47 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).errors.txt @@ -0,0 +1,177 @@ +tests/cases/conformance/node/index.cts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.cts(9,24): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. +tests/cases/conformance/node/index.mts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.mts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.mts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/index.ts(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. +tests/cases/conformance/node/node_modules/inner/index.d.cts(3,22): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. +tests/cases/conformance/node/node_modules/inner/index.d.ts(2,13): error TS2303: Circular definition of import alias 'cjs'. +tests/cases/conformance/node/node_modules/inner/index.d.ts(3,22): error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + + +==== tests/cases/conformance/node/index.ts (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/index.mts (3 errors) ==== + // esm format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/index.cts (4 errors) ==== + // cjs format file + import * as cjsi from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjsi from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as typei from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + cjsi; + mjsi; + typei; + import * as cjsi2 from "inner/cjs/index"; + import * as mjsi2 from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as typei2 from "inner/js/index"; + cjsi2; + mjsi2; + typei2; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts (3 errors) ==== + // esm format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts (3 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations. + import * as mjs from "inner/mjs/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations. + import * as type from "inner/js/exclude/index"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations. + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.ts (2 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/index"; + ~~~ +!!! error TS2303: Circular definition of import alias 'cjs'. + import * as mjs from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.mts (0 errors) ==== + // esm format file + import * as cjs from "inner/cjs/index"; + import * as mjs from "inner/mjs/index"; + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/node_modules/inner/index.d.cts (1 errors) ==== + // cjs format file + import * as cjs from "inner/cjs/index"; + import * as mjs from "inner/mjs/index"; + ~~~~~~~~~~~~~~~~~ +!!! error TS1471: Module 'inner/mjs/index' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead. + import * as type from "inner/js/index"; + export { cjs }; + export { mjs }; + export { type }; +==== tests/cases/conformance/node/package.json (0 errors) ==== + { + "name": "package", + "private": true, + "type": "module" + } +==== tests/cases/conformance/node/node_modules/inner/package.json (0 errors) ==== + { + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).js b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).js new file mode 100644 index 00000000000..5c3a1fea219 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).js @@ -0,0 +1,187 @@ +//// [tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts] //// + +//// [index.ts] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.mts] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.cts] +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.ts] +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.mts] +// esm format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [index.d.cts] +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +//// [package.json] +{ + "name": "package", + "private": true, + "type": "module" +} +//// [package.json] +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} + +//// [index.js] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.mjs] +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +//// [index.cjs] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// cjs format file +const cjsi = __importStar(require("inner/cjs/exclude/index")); +const mjsi = __importStar(require("inner/mjs/exclude/index")); +const typei = __importStar(require("inner/js/exclude/index")); +cjsi; +mjsi; +typei; +const cjsi2 = __importStar(require("inner/cjs/index")); +const mjsi2 = __importStar(require("inner/mjs/index")); +const typei2 = __importStar(require("inner/js/index")); +cjsi2; +mjsi2; +typei2; + + +//// [index.d.ts] +export {}; +//// [index.d.mts] +export {}; +//// [index.d.cts] +export {}; diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).symbols b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).symbols new file mode 100644 index 00000000000..6114f146f23 --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).symbols @@ -0,0 +1,234 @@ +=== tests/cases/conformance/node/index.ts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.ts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.ts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.ts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.ts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.ts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.ts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.ts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.ts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.ts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.ts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.ts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.ts, 9, 6)) + +=== tests/cases/conformance/node/index.mts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.mts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.mts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.mts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.mts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.mts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.mts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.mts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.mts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.mts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.mts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.mts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.mts, 9, 6)) + +=== tests/cases/conformance/node/index.cts === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : Symbol(cjsi, Decl(index.cts, 1, 6)) + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : Symbol(mjsi, Decl(index.cts, 2, 6)) + +import * as typei from "inner/js/exclude/index"; +>typei : Symbol(typei, Decl(index.cts, 3, 6)) + +cjsi; +>cjsi : Symbol(cjsi, Decl(index.cts, 1, 6)) + +mjsi; +>mjsi : Symbol(mjsi, Decl(index.cts, 2, 6)) + +typei; +>typei : Symbol(typei, Decl(index.cts, 3, 6)) + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : Symbol(cjsi2, Decl(index.cts, 7, 6)) + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : Symbol(mjsi2, Decl(index.cts, 8, 6)) + +import * as typei2 from "inner/js/index"; +>typei2 : Symbol(typei2, Decl(index.cts, 9, 6)) + +cjsi2; +>cjsi2 : Symbol(cjsi2, Decl(index.cts, 7, 6)) + +mjsi2; +>mjsi2 : Symbol(mjsi2, Decl(index.cts, 8, 6)) + +typei2; +>typei2 : Symbol(typei2, Decl(index.cts, 9, 6)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/exclude/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(type, Decl(index.d.cts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.ts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.ts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.ts, 3, 6)) + +export { cjs }; +>cjs : Symbol(mjs.cjs.cjs.type.cjs, Decl(index.d.ts, 4, 8)) + +export { mjs }; +>mjs : Symbol(mjs.cjs.cjs.type.mjs, Decl(index.d.ts, 5, 8)) + +export { type }; +>type : Symbol(mjs.cjs.cjs.type.type, Decl(index.d.ts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.mts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.mts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.mts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs.cjs.mjs.cjs, Decl(index.d.mts, 4, 8)) + +export { mjs }; +>mjs : Symbol(cjs.cjs.mjs.mjs, Decl(index.d.mts, 5, 8)) + +export { type }; +>type : Symbol(cjs.cjs.mjs.type, Decl(index.d.mts, 6, 8)) + +=== tests/cases/conformance/node/node_modules/inner/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : Symbol(cjs, Decl(index.d.cts, 1, 6)) + +import * as mjs from "inner/mjs/index"; +>mjs : Symbol(mjs, Decl(index.d.cts, 2, 6)) + +import * as type from "inner/js/index"; +>type : Symbol(type, Decl(index.d.cts, 3, 6)) + +export { cjs }; +>cjs : Symbol(cjs.cjs, Decl(index.d.cts, 4, 8)) + +export { mjs }; +>mjs : Symbol(cjs.mjs, Decl(index.d.cts, 5, 8)) + +export { type }; +>type : Symbol(cjs.type, Decl(index.d.cts, 6, 8)) + diff --git a/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).types b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).types new file mode 100644 index 00000000000..517f6dfa99b --- /dev/null +++ b/tests/baselines/reference/nodeModulesPackagePatternExportsExclude(module=nodenext).types @@ -0,0 +1,234 @@ +=== tests/cases/conformance/node/index.ts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.cjs.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof typei2 + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.cjs.mjs + +typei2; +>typei2 : typeof typei2 + +=== tests/cases/conformance/node/index.mts === +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.cjs.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof typei2 + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.cjs.mjs + +typei2; +>typei2 : typeof typei2 + +=== tests/cases/conformance/node/index.cts === +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +>cjsi : any + +import * as mjsi from "inner/mjs/exclude/index"; +>mjsi : any + +import * as typei from "inner/js/exclude/index"; +>typei : any + +cjsi; +>cjsi : any + +mjsi; +>mjsi : any + +typei; +>typei : any + +import * as cjsi2 from "inner/cjs/index"; +>cjsi2 : typeof cjsi2 + +import * as mjsi2 from "inner/mjs/index"; +>mjsi2 : typeof cjsi2.mjs + +import * as typei2 from "inner/js/index"; +>typei2 : typeof cjsi2.mjs.cjs.type + +cjsi2; +>cjsi2 : typeof cjsi2 + +mjsi2; +>mjsi2 : typeof cjsi2.mjs + +typei2; +>typei2 : typeof cjsi2.mjs.cjs.type + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/exclude/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +>cjs : any + +import * as mjs from "inner/mjs/exclude/index"; +>mjs : any + +import * as type from "inner/js/exclude/index"; +>type : any + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : any + +export { type }; +>type : any + +=== tests/cases/conformance/node/node_modules/inner/index.d.ts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : any + +import * as mjs from "inner/mjs/index"; +>mjs : typeof mjs + +import * as type from "inner/js/index"; +>type : typeof mjs.cjs.cjs.type + +export { cjs }; +>cjs : any + +export { mjs }; +>mjs : typeof mjs + +export { type }; +>type : typeof mjs.cjs.cjs.type + +=== tests/cases/conformance/node/node_modules/inner/index.d.mts === +// esm format file +import * as cjs from "inner/cjs/index"; +>cjs : typeof cjs + +import * as mjs from "inner/mjs/index"; +>mjs : typeof cjs.cjs.mjs + +import * as type from "inner/js/index"; +>type : typeof cjs.cjs.mjs.type + +export { cjs }; +>cjs : typeof cjs + +export { mjs }; +>mjs : typeof cjs.cjs.mjs + +export { type }; +>type : typeof cjs.cjs.mjs.type + +=== tests/cases/conformance/node/node_modules/inner/index.d.cts === +// cjs format file +import * as cjs from "inner/cjs/index"; +>cjs : typeof cjs + +import * as mjs from "inner/mjs/index"; +>mjs : typeof cjs.mjs + +import * as type from "inner/js/index"; +>type : typeof cjs.mjs.cjs.type + +export { cjs }; +>cjs : typeof cjs + +export { mjs }; +>mjs : typeof cjs.mjs + +export { type }; +>type : typeof cjs.mjs.cjs.type + diff --git a/tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts b/tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts new file mode 100644 index 00000000000..f402a08f651 --- /dev/null +++ b/tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts @@ -0,0 +1,72 @@ +// @module: node16,nodenext +// @declaration: true +// @allowJs: true +// @checkJs: true +// @outDir: out +// @filename: index.js +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +// @filename: index.mjs +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +// @filename: index.cjs +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +// @filename: node_modules/inner/exclude/index.d.ts +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/exclude/index.d.mts +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/exclude/index.d.cts +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: package.json +{ + "name": "package", + "private": true, + "type": "module" +} +// @filename: node_modules/inner/package.json +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} \ No newline at end of file diff --git a/tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts b/tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts new file mode 100644 index 00000000000..a12b1dab20d --- /dev/null +++ b/tests/cases/conformance/node/nodeModulesPackagePatternExportsExclude.ts @@ -0,0 +1,112 @@ +// @module: node16,nodenext +// @declaration: true +// @outDir: out +// @filename: index.ts +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +// @filename: index.mts +// esm format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +// @filename: index.cts +// cjs format file +import * as cjsi from "inner/cjs/exclude/index"; +import * as mjsi from "inner/mjs/exclude/index"; +import * as typei from "inner/js/exclude/index"; +cjsi; +mjsi; +typei; +import * as cjsi2 from "inner/cjs/index"; +import * as mjsi2 from "inner/mjs/index"; +import * as typei2 from "inner/js/index"; +cjsi2; +mjsi2; +typei2; +// @filename: node_modules/inner/exclude/index.d.ts +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/exclude/index.d.mts +// esm format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/exclude/index.d.cts +// cjs format file +import * as cjs from "inner/cjs/exclude/index"; +import * as mjs from "inner/mjs/exclude/index"; +import * as type from "inner/js/exclude/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/index.d.ts +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/index.d.mts +// esm format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: node_modules/inner/index.d.cts +// cjs format file +import * as cjs from "inner/cjs/index"; +import * as mjs from "inner/mjs/index"; +import * as type from "inner/js/index"; +export { cjs }; +export { mjs }; +export { type }; +// @filename: package.json +{ + "name": "package", + "private": true, + "type": "module" +} +// @filename: node_modules/inner/package.json +{ + "name": "inner", + "private": true, + "exports": { + "./cjs/*": "./*.cjs", + "./cjs/exclude/*": null, + "./mjs/*": "./*.mjs", + "./mjs/exclude/*": null, + "./js/*": "./*.js", + "./js/exclude/*": null + } +} \ No newline at end of file From 34fe835f33d3bbfa1a2d971190152dda5349176c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 2 Jun 2022 15:50:44 -0700 Subject: [PATCH 15/17] Add nightly-only error on ImportType resolution mode assertion (#49356) * Add nightly-only error on ImportType resolution mode assertion * Temporarily change version to demonstrate errors * Revert "Temporarily change version to demonstrate errors" This reverts commit 40c2469647f129ea088a16d60f3f070f9f5beeb2. * "Resolution mode" -> "resolution-mode" --- src/compiler/checker.ts | 11 ++++++++--- src/compiler/diagnosticMessages.json | 8 ++++++-- src/compiler/program.ts | 2 +- src/compiler/transformers/declarations.ts | 11 +++++++++-- src/compiler/types.ts | 1 + ...ReferenceModeOverrideOldResolutionError.errors.txt | 8 ++++---- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62241eda9d8..617934cbb38 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6224,6 +6224,7 @@ namespace ts { factory.createStringLiteral("import") ) ]))); + context.tracker.reportImportTypeNodeResolutionModeOverride?.(); } } if (!specifier) { @@ -6247,6 +6248,7 @@ namespace ts { factory.createStringLiteral(swappedMode === ModuleKind.ESNext ? "import" : "require") ) ]))); + context.tracker.reportImportTypeNodeResolutionModeOverride?.(); } } @@ -36029,8 +36031,11 @@ namespace ts { if (node.assertions) { const override = getResolutionModeOverrideForClause(node.assertions.assertClause, grammarErrorOnNode); if (override) { + if (!isNightly()) { + grammarErrorOnNode(node.assertions.assertClause, Diagnostics.resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next); + } if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { - grammarErrorOnNode(node.assertions.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); + grammarErrorOnNode(node.assertions.assertClause, Diagnostics.resolution_mode_assertions_are_only_supported_when_moduleResolution_is_node16_or_nodenext); } } } @@ -40961,11 +40966,11 @@ namespace ts { const override = getResolutionModeOverrideForClause(declaration.assertClause, validForTypeAssertions ? grammarErrorOnNode : undefined); if (validForTypeAssertions && override) { if (!isNightly()) { - grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next); + grammarErrorOnNode(declaration.assertClause, Diagnostics.resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next); } if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { - return grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); + return grammarErrorOnNode(declaration.assertClause, Diagnostics.resolution_mode_assertions_are_only_supported_when_moduleResolution_is_node16_or_nodenext); } return; // Other grammar checks do not apply to type-only imports with resolution mode assertions } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 51e4a59cca2..6078b781250 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1440,7 +1440,7 @@ "category": "Error", "code": 1451 }, - "Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`.": { + "'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`.": { "category": "Error", "code": 1452 }, @@ -3483,6 +3483,10 @@ "category": "Error", "code": 2840 }, + "The type of this expression cannot be named without a 'resolution-mode' assertion, which is an unstable feature. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": { + "category": "Error", + "code": 2841 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", @@ -3912,7 +3916,7 @@ "category": "Error", "code": 4124 }, - "Resolution mode assertions are unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": { + "'resolution-mode' assertions are unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": { "category": "Error", "code": 4125 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index aa106a61873..fbb5be6c7f1 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3121,7 +3121,7 @@ namespace ts { setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective); const mode = ref.resolutionMode || file.impliedNodeFormat; if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) { - programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext)); + programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.resolution_mode_assertions_are_only_supported_when_moduleResolution_is_node16_or_nodenext)); } processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: FileIncludeKind.TypeReferenceDirective, file: file.path, index, }); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index b855fd4b8da..76db95b2603 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -78,7 +78,8 @@ namespace ts { trackReferencedAmbientModule, trackExternalModuleSymbolOfImportTypeNode, reportNonlocalAugmentation, - reportNonSerializableProperty + reportNonSerializableProperty, + reportImportTypeNodeResolutionModeOverride, }; let errorNameNode: DeclarationName | undefined; let errorFallbackNode: Declaration | undefined; @@ -235,6 +236,12 @@ namespace ts { } } + function reportImportTypeNodeResolutionModeOverride() { + if (!isNightly() && (errorNameNode || errorFallbackNode)) { + context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_type_of_this_expression_cannot_be_named_without_a_resolution_mode_assertion_which_is_an_unstable_feature_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next)); + } + } + function transformDeclarationsForJS(sourceFile: SourceFile, bundled?: boolean) { const oldDiag = getSymbolAccessibilityDiagnostic; getSymbolAccessibilityDiagnostic = (s) => (s.errorNode && canProduceDiagnostics(s.errorNode) ? createGetSymbolAccessibilityDiagnosticForNode(s.errorNode)(s) : ({ @@ -792,7 +799,7 @@ namespace ts { const mode = getResolutionModeOverrideForClause(assertClause); if (mode !== undefined) { if (!isNightly()) { - context.addDiagnostic(createDiagnosticForNode(assertClause!, Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next)); + context.addDiagnostic(createDiagnosticForNode(assertClause!, Diagnostics.resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next)); } return assertClause; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5aca9584a99..8d5662ac2cf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8524,6 +8524,7 @@ namespace ts { trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void; reportNonlocalAugmentation?(containingFile: SourceFile, parentSymbol: Symbol, augmentingSymbol: Symbol): void; reportNonSerializableProperty?(propertyName: string): void; + reportImportTypeNodeResolutionModeOverride?(): void; } export interface TextSpan { diff --git a/tests/baselines/reference/nodeModulesTripleSlashReferenceModeOverrideOldResolutionError.errors.txt b/tests/baselines/reference/nodeModulesTripleSlashReferenceModeOverrideOldResolutionError.errors.txt index 05f937c37ad..fcec678778d 100644 --- a/tests/baselines/reference/nodeModulesTripleSlashReferenceModeOverrideOldResolutionError.errors.txt +++ b/tests/baselines/reference/nodeModulesTripleSlashReferenceModeOverrideOldResolutionError.errors.txt @@ -1,6 +1,6 @@ -/index.ts(1,23): error TS1452: Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`. +/index.ts(1,23): error TS1452: 'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`. /index.ts(1,23): error TS2688: Cannot find type definition file for 'pkg'. -/index.ts(2,23): error TS1452: Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`. +/index.ts(2,23): error TS1452: 'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`. /index.ts(2,23): error TS2688: Cannot find type definition file for 'pkg'. /index.ts(3,1): error TS2304: Cannot find name 'foo'. /index.ts(4,1): error TS2304: Cannot find name 'bar'. @@ -9,12 +9,12 @@ ==== /index.ts (6 errors) ==== /// ~~~ -!!! error TS1452: Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`. +!!! error TS1452: 'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`. ~~~ !!! error TS2688: Cannot find type definition file for 'pkg'. /// ~~~ -!!! error TS1452: Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`. +!!! error TS1452: 'resolution-mode' assertions are only supported when `moduleResolution` is `node16` or `nodenext`. ~~~ !!! error TS2688: Cannot find type definition file for 'pkg'. foo; // `resolution-mode` is an error in old resolution settings, which resolves is arbitrary From 9c8e6b53b8237663669577665f3e4e6ec8da8530 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 3 Jun 2022 03:28:36 +0300 Subject: [PATCH 16/17] fix(49223): checker.getTypeAtLocation for ExpressionWithTypeArguments returns an error any type (#49284) * fix(49223): handle ExpressionWithTypeArguments nodes in isExpressionNode * Update src/compiler/utilities.ts * Just use `!isHeritageClause(node.parent)`. Co-authored-by: Daniel Rosenwasser --- src/compiler/utilities.ts | 2 ++ src/testRunner/unittests/publicApi.ts | 24 +++++++++++++ .../reference/genericCallWithoutArgs.types | 1 + .../reference/importWithTypeArguments.types | 3 ++ .../instantiationExpressionErrors.types | 13 +++++++ .../reference/instantiationExpressions.types | 34 +++++++++++++++++++ .../parserMemberAccessExpression1.types | 2 ++ .../parserMemberAccessOffOfGenericType1.types | 1 + 8 files changed, 80 insertions(+) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e6e42de221c..5d118e9958b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2016,6 +2016,8 @@ namespace ts { case SyntaxKind.AwaitExpression: case SyntaxKind.MetaProperty: return true; + case SyntaxKind.ExpressionWithTypeArguments: + return !isHeritageClause(node.parent); case SyntaxKind.QualifiedName: while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; diff --git a/src/testRunner/unittests/publicApi.ts b/src/testRunner/unittests/publicApi.ts index 4bfce8288f5..00d8994520f 100644 --- a/src/testRunner/unittests/publicApi.ts +++ b/src/testRunner/unittests/publicApi.ts @@ -131,6 +131,30 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => { assert.equal(type.flags, ts.TypeFlags.Any); }); + it("works on ExpressionWithTypeArguments", () => { + const content = ` + function fn(value: T) { + return { value }; + } + const foo = fn; + `; + const host = new fakes.CompilerHost(vfs.createFromFileSystem( + Harness.IO, + /*ignoreCase*/ true, + { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); + + const program = ts.createProgram({ + host, + rootNames: ["/file.ts"], + options: { noLib: true } + }); + + const checker = program.getTypeChecker(); + const file = program.getSourceFile("/file.ts")!; + const [declaration] = (ts.findLast(file.statements, ts.isVariableStatement) as ts.VariableStatement).declarationList.declarations; + assert.equal(checker.getTypeAtLocation(declaration.initializer!).flags, ts.TypeFlags.Object); + }); + it("returns an errorType for VariableDeclaration with BindingPattern name", () => { const content = "const foo = [1];\n" + "const [a] = foo;"; diff --git a/tests/baselines/reference/genericCallWithoutArgs.types b/tests/baselines/reference/genericCallWithoutArgs.types index 82c32a2ad04..6d4969a83ee 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.types +++ b/tests/baselines/reference/genericCallWithoutArgs.types @@ -7,6 +7,7 @@ function f(x: X, y: Y) { f. >f. : any +>f : (x: number, y: string) => void >f : (x: X, y: Y) => void > : any diff --git a/tests/baselines/reference/importWithTypeArguments.types b/tests/baselines/reference/importWithTypeArguments.types index 442b3cc9ed9..2998bd6f20e 100644 --- a/tests/baselines/reference/importWithTypeArguments.types +++ b/tests/baselines/reference/importWithTypeArguments.types @@ -1,5 +1,8 @@ === tests/cases/conformance/types/import/importWithTypeArguments.ts === import +>import : any + const a = import >a : any +>import : any diff --git a/tests/baselines/reference/instantiationExpressionErrors.types b/tests/baselines/reference/instantiationExpressionErrors.types index 334cb69865e..c2de6b5720e 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.types +++ b/tests/baselines/reference/instantiationExpressionErrors.types @@ -7,10 +7,12 @@ declare let f: { (): T, g(): U }; const a1 = f; // { (): number; g(): U; } >a1 : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } const a2 = f.g; // () => number >a2 : () => number +>f.g : () => number >f.g : () => U >f : { (): T; g(): U; } >g : () => U @@ -18,17 +20,21 @@ const a2 = f.g; // () => number const a3 = f.g; // () => U >a3 : () => U >f.g : () => U +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >g : () => U const a4 = f.g; // () => number >a4 : () => number +>f.g : () => number >f.g : () => U +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >g : () => U const a5 = f['g']; // () => number >a5 : () => number +>f['g'] : () => number >f['g'] : () => U >f : { (): T; g(): U; } >'g' : "g" @@ -48,6 +54,7 @@ const a7 = (f)['g']; >a7 : () => U >(f)['g'] : () => U >(f) : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >'g' : "g" @@ -64,7 +71,9 @@ const a8 = f; // Relational operator error const a9 = (f); // Error, no applicable signatures >a9 : { g(): U; } +>(f) : { g(): U; } >(f) : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } // Type arguments with `?.` token @@ -82,11 +91,13 @@ const b2 = f?.(); const b3 = f?.(); >b3 : number >f?.() : number +>f : { (): number; g(): U; } >f : { (): T; g(): U; } const b4 = f?.(); // Error, expected no type arguments >b4 : number >f?.() : number +>f : { (): number; g(): U; } >f : { (): T; g(): U; } // Parsed as function call, even though this differs from JavaScript @@ -116,6 +127,7 @@ true; const x3 = f; >x3 : { (): true; g(): U; } +>f : { (): true; g(): U; } >f : { (): T; g(): U; } >true : true @@ -126,6 +138,7 @@ true; const x4 = f >x4 : { (): true; g(): U; } +>f : { (): true; g(): U; } >f : { (): T; g(): U; } >true : true diff --git a/tests/baselines/reference/instantiationExpressions.types b/tests/baselines/reference/instantiationExpressions.types index bb35bc036a1..75fe72fc441 100644 --- a/tests/baselines/reference/instantiationExpressions.types +++ b/tests/baselines/reference/instantiationExpressions.types @@ -17,18 +17,22 @@ function f1() { let f0 = fx<>; // Error >f0 : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>fx<> : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f1 = fx; // { (x: string): string; (x: string, n: number): string; } >f1 : { (x: string): string; (x: string, n: number): string; } +>fx : { (x: string): string; (x: string, n: number): string; } >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f2 = fx; // (t: [string, number]) => [string, number] >f2 : (t: [string, number]) => [string, number] +>fx : (t: [string, number]) => [string, number] >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f3 = fx; // Error >f3 : {} +>fx : {} >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } } @@ -53,14 +57,17 @@ function f2() { const A0 = Array<>; // Error >A0 : ArrayConstructor +>Array<> : ArrayConstructor >Array : ArrayConstructor const A1 = Array; // new (...) => string[] >A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor const A2 = Array; // Error >A2 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor } @@ -92,10 +99,12 @@ function f3() { let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } >c1 : { new (x: string): C; prototype: C; f(x: U): U[]; } +>C : { new (x: string): C; prototype: C; f(x: U): U[]; } >C : typeof C let f1 = C.f; // (x: string) => string[] >f1 : (x: string) => string[] +>C.f : (x: string) => string[] >C.f : (x: U) => U[] >C : typeof C >f : (x: U) => U[] @@ -110,6 +119,7 @@ function f10(f: { (a: T): T, (a: U, b: number): U[] }) { let fs = f; // { (a: string): string; (a: string, b: number): string[]; } >fs : { (a: string): string; (a: string, b: number): string[]; } +>f : { (a: string): string; (a: string, b: number): string[]; } >f : { (a: T): T; (a: U, b: number): U[]; } } @@ -122,6 +132,7 @@ function f11(f: { (a: T): T, (a: string, b: number): string[] }) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : { (a: T): T; (a: string, b: number): string[]; } } @@ -133,6 +144,7 @@ function f12(f: { (a: T): T, x: string }) { let fs = f; // { (a: string): string; x: string; } >fs : { (a: string): string; x: string; } +>f : { (a: string): string; x: string; } >f : { (a: T): T; x: string; } } @@ -144,6 +156,7 @@ function f13(f: { x: string, y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; y: string; } +>f : { x: string; y: string; } >f : { x: string; y: string; } } @@ -156,6 +169,7 @@ function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } >fs : { new (a: string): string; new (a: string, b: number): string[]; } +>f : { new (a: string): string; new (a: string, b: number): string[]; } >f : { new (a: T): T; new (a: U, b: number): U[]; } } @@ -168,6 +182,7 @@ function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } >fs : { (a: string, b: number): string[]; new (a: string): string; } +>f : { (a: string, b: number): string[]; new (a: string): string; } >f : { (a: U, b: number): U[]; new (a: T): T; } } @@ -180,6 +195,7 @@ function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { let fs = f; // new (a: string) => string >fs : new (a: string) => string +>f : new (a: string) => string >f : { (a: string, b: number): string[]; new (a: T): T; } } @@ -192,6 +208,7 @@ function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : { (a: T): T; new (a: string, b: number): string[]; } } @@ -204,6 +221,7 @@ function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) >fs : ((a: string) => string) & ((a: string, b: number) => string[]) +>f : ((a: string) => string) & ((a: string, b: number) => string[]) >f : ((a: T) => T) & ((a: U, b: number) => U[]) } @@ -216,6 +234,7 @@ function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : ((a: T) => T) & ((a: string, b: number) => string[]) } @@ -227,6 +246,7 @@ function f22(f: ((a: T) => T) & { x: string }) { let fs = f; // ((a: string) => string) & { x: string } >fs : ((a: string) => string) & { x: string; } +>f : ((a: string) => string) & { x: string; } >f : ((a: T) => T) & { x: string; } } @@ -238,6 +258,7 @@ function f23(f: { x: string } & { y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; } & { y: string; } +>f : { x: string; } & { y: string; } >f : { x: string; } & { y: string; } } @@ -250,6 +271,7 @@ function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) & (new (a: string, b: number) => string[]) +>f : (new (a: string) => string) & (new (a: string, b: number) => string[]) >f : (new (a: T) => T) & (new (a: U, b: number) => U[]) } @@ -262,6 +284,7 @@ function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) & ((a: string, b: number) => string[]) +>f : (new (a: string) => string) & ((a: string, b: number) => string[]) >f : (new (a: T) => T) & ((a: U, b: number) => U[]) } @@ -274,6 +297,7 @@ function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { let fs = f; // new (a: string) => string >fs : new (a: string) => string +>f : new (a: string) => string >f : (new (a: T) => T) & ((a: string, b: number) => string[]) } @@ -286,6 +310,7 @@ function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : ((a: T) => T) & (new (a: string, b: number) => string[]) } @@ -298,6 +323,7 @@ function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) >fs : ((a: string) => string) | ((a: string, b: number) => string[]) +>f : ((a: string) => string) | ((a: string, b: number) => string[]) >f : ((a: T) => T) | ((a: U, b: number) => U[]) } @@ -310,6 +336,7 @@ function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures >fs : ((a: string) => string) | {} +>f : ((a: string) => string) | {} >f : ((a: T) => T) | ((a: string, b: number) => string[]) } @@ -321,6 +348,7 @@ function f32(f: ((a: T) => T) | { x: string }) { let fs = f; // ((a: string) => string) | { x: string } >fs : { x: string; } | ((a: string) => string) +>f : { x: string; } | ((a: string) => string) >f : { x: string; } | ((a: T) => T) } @@ -332,6 +360,7 @@ function f33(f: { x: string } | { y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; } | { y: string; } +>f : { x: string; } | { y: string; } >f : { x: string; } | { y: string; } } @@ -344,6 +373,7 @@ function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) | (new (a: string, b: number) => string[]) +>f : (new (a: string) => string) | (new (a: string, b: number) => string[]) >f : (new (a: T) => T) | (new (a: U, b: number) => U[]) } @@ -356,6 +386,7 @@ function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) | ((a: string, b: number) => string[]) +>f : (new (a: string) => string) | ((a: string, b: number) => string[]) >f : (new (a: T) => T) | ((a: U, b: number) => U[]) } @@ -368,6 +399,7 @@ function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures >fs : (new (a: string) => string) | {} +>f : (new (a: string) => string) | {} >f : (new (a: T) => T) | ((a: string, b: number) => string[]) } @@ -380,6 +412,7 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures >fs : ((a: string) => string) | {} +>f : ((a: string) => string) | {} >f : ((a: T) => T) | (new (a: string, b: number) => string[]) } @@ -392,6 +425,7 @@ function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ( let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) >fs : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +>f : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) >f : T | U | ((x: C) => C[][]) } diff --git a/tests/baselines/reference/parserMemberAccessExpression1.types b/tests/baselines/reference/parserMemberAccessExpression1.types index 08299f7dfd7..395f91b2450 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.types +++ b/tests/baselines/reference/parserMemberAccessExpression1.types @@ -12,12 +12,14 @@ Foo.Bar(); Foo.Bar(); >Foo.Bar() : any >Foo.Bar : any +>Foo : any >Foo : any >Bar : any Foo.Bar(); >Foo.Bar() : any >Foo.Bar : any +>Foo : any >Foo : any >Bar : any diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types index 2bd59381f87..b89005fb0ca 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types @@ -3,6 +3,7 @@ var v = List.makeChild(); >v : any >List.makeChild() : any >List.makeChild : any +>List : any >List : any >makeChild : any From 3ccbe804f850f40d228d3c875be952d94d39aa1d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 2 Jun 2022 18:06:50 -0700 Subject: [PATCH 17/17] Expose import mode calculation functions (#49360) * Expose import mode calculation functions * Make `SourceFileImportsList` internal again. * Accepted API baselines. * Fix lints. Co-authored-by: Daniel Rosenwasser --- src/compiler/program.ts | 43 +++++++++++++++---- .../reference/api/tsserverlibrary.d.ts | 25 +++++++++++ tests/baselines/reference/api/typescript.d.ts | 25 +++++++++++ 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index fbb5be6c7f1..3e74a820651 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -536,20 +536,39 @@ namespace ts { return resolutions; } - /* @internal */ - interface SourceFileImportsList { - imports: SourceFile["imports"]; - moduleAugmentations: SourceFile["moduleAugmentations"]; + /** + * Subset of a SourceFile used to calculate index-based resolutions + * This includes some internal fields, so unless you have very good reason, + * (and are willing to use some less stable internals) you should probably just pass a SourceFile. + * + * @internal + */ + export interface SourceFileImportsList { + /* @internal */ imports: SourceFile["imports"]; + /* @internal */ moduleAugmentations: SourceFile["moduleAugmentations"]; impliedNodeFormat?: SourceFile["impliedNodeFormat"]; }; - /* @internal */ + /** + * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly + * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. + */ export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]) { return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode; } - /* @internal */ - export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number) { + /** + * Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly + * defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm). + * If you have an actual import node, prefer using getModeForUsageLocation on the reference string node. + * @param file File to fetch the resolution mode within + * @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations + */ + export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + /** @internal */ + // eslint-disable-next-line @typescript-eslint/unified-signatures + export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined { if (file.impliedNodeFormat === undefined) return undefined; // we ensure all elements of file.imports and file.moduleAugmentations have the relevant parent pointers set during program setup, // so it's safe to use them even pre-bind @@ -567,7 +586,15 @@ namespace ts { return false; } - /* @internal */ + /** + * Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if + * one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm). + * Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when + * `moduleResolution` is `node16`+. + * @param file The file the import or import-like reference is contained within + * @param usage The module reference string + * @returns The final resolution mode of the import + */ export function getModeForUsageLocation(file: {impliedNodeFormat?: SourceFile["impliedNodeFormat"]}, usage: StringLiteralLike) { if (file.impliedNodeFormat === undefined) return undefined; if ((isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent))) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 25b43264785..83d181787c6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5103,6 +5103,31 @@ declare namespace ts { export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string; export function formatDiagnosticsWithColorAndContext(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string; export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string; + /** + * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly + * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. + */ + export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + /** + * Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly + * defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm). + * If you have an actual import node, prefer using getModeForUsageLocation on the reference string node. + * @param file File to fetch the resolution mode within + * @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations + */ + export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + /** + * Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if + * one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm). + * Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when + * `moduleResolution` is `node16`+. + * @param file The file the import or import-like reference is contained within + * @param usage The module reference string + * @returns The final resolution mode of the import + */ + export function getModeForUsageLocation(file: { + impliedNodeFormat?: SourceFile["impliedNodeFormat"]; + }, usage: StringLiteralLike): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[]; /** * A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1012dbe8bf8..5d4ce61f174 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5103,6 +5103,31 @@ declare namespace ts { export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string; export function formatDiagnosticsWithColorAndContext(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string; export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string; + /** + * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly + * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. + */ + export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + /** + * Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly + * defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm). + * If you have an actual import node, prefer using getModeForUsageLocation on the reference string node. + * @param file File to fetch the resolution mode within + * @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations + */ + export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; + /** + * Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if + * one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm). + * Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when + * `moduleResolution` is `node16`+. + * @param file The file the import or import-like reference is contained within + * @param usage The module reference string + * @returns The final resolution mode of the import + */ + export function getModeForUsageLocation(file: { + impliedNodeFormat?: SourceFile["impliedNodeFormat"]; + }, usage: StringLiteralLike): ModuleKind.CommonJS | ModuleKind.ESNext | undefined; export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[]; /** * A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the