diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32086157552..8f8be4a10ef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3398,7 +3398,7 @@ namespace ts { else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral && type.symbol.valueDeclaration && type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { - writeAnonymousType(getDeclaredTypeOfClassOrInterface(type.symbol), flags); + writeAnonymousType(type, flags); } else { // Write the type reference in the format f.g.C where A and B are type arguments diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.js b/tests/baselines/reference/declarationNoDanglingGenerics.js new file mode 100644 index 00000000000..9045be6827b --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.js @@ -0,0 +1,125 @@ +//// [declarationNoDanglingGenerics.ts] +const kindCache: { [kind: string]: boolean } = {}; + +function register(kind: string): void | never { + if (kindCache[kind]) { + throw new Error(`Class with kind "${kind}" is already registered.`); + } + kindCache[kind] = true; +} + +function ClassFactory(kind: TKind) { + register(kind); + + return class { + static readonly THE_KIND: TKind = kind; + readonly kind: TKind = kind; + }; +} + +class Kinds { + static readonly A = "A"; + static readonly B = "B"; + static readonly C = "C"; +} + +export class AKind extends ClassFactory(Kinds.A) { +} + +export class BKind extends ClassFactory(Kinds.B) { +} + +export class CKind extends ClassFactory(Kinds.C) { +} + +//// [declarationNoDanglingGenerics.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var kindCache = {}; +function register(kind) { + if (kindCache[kind]) { + throw new Error("Class with kind \"" + kind + "\" is already registered."); + } + kindCache[kind] = true; +} +function ClassFactory(kind) { + register(kind); + return _a = /** @class */ (function () { + function class_1() { + this.kind = kind; + } + return class_1; + }()), + _a.THE_KIND = kind, + _a; + var _a; +} +var Kinds = /** @class */ (function () { + function Kinds() { + } + Kinds.A = "A"; + Kinds.B = "B"; + Kinds.C = "C"; + return Kinds; +}()); +var AKind = /** @class */ (function (_super) { + __extends(AKind, _super); + function AKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AKind; +}(ClassFactory(Kinds.A))); +exports.AKind = AKind; +var BKind = /** @class */ (function (_super) { + __extends(BKind, _super); + function BKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return BKind; +}(ClassFactory(Kinds.B))); +exports.BKind = BKind; +var CKind = /** @class */ (function (_super) { + __extends(CKind, _super); + function CKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return CKind; +}(ClassFactory(Kinds.C))); +exports.CKind = CKind; + + +//// [declarationNoDanglingGenerics.d.ts] +declare const AKind_base: { + new (): { + readonly kind: "A"; + }; + readonly THE_KIND: "A"; +}; +export declare class AKind extends AKind_base { +} +declare const BKind_base: { + new (): { + readonly kind: "B"; + }; + readonly THE_KIND: "B"; +}; +export declare class BKind extends BKind_base { +} +declare const CKind_base: { + new (): { + readonly kind: "C"; + }; + readonly THE_KIND: "C"; +}; +export declare class CKind extends CKind_base { +} diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.symbols b/tests/baselines/reference/declarationNoDanglingGenerics.symbols new file mode 100644 index 00000000000..512bf95d4bb --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.symbols @@ -0,0 +1,82 @@ +=== tests/cases/compiler/declarationNoDanglingGenerics.ts === +const kindCache: { [kind: string]: boolean } = {}; +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 0, 20)) + +function register(kind: string): void | never { +>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + + if (kindCache[kind]) { +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + + throw new Error(`Class with kind "${kind}" is already registered.`); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + } + kindCache[kind] = true; +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) +} + +function ClassFactory(kind: TKind) { +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) + + register(kind); +>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + return class { + static readonly THE_KIND: TKind = kind; +>THE_KIND : Symbol((Anonymous class).THE_KIND, Decl(declarationNoDanglingGenerics.ts, 12, 16)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + readonly kind: TKind = kind; +>kind : Symbol((Anonymous class).kind, Decl(declarationNoDanglingGenerics.ts, 13, 43)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + }; +} + +class Kinds { +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) + + static readonly A = "A"; +>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) + + static readonly B = "B"; +>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) + + static readonly C = "C"; +>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +} + +export class AKind extends ClassFactory(Kinds.A) { +>AKind : Symbol(AKind, Decl(declarationNoDanglingGenerics.ts, 22, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) +} + +export class BKind extends ClassFactory(Kinds.B) { +>BKind : Symbol(BKind, Decl(declarationNoDanglingGenerics.ts, 25, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) +} + +export class CKind extends ClassFactory(Kinds.C) { +>CKind : Symbol(CKind, Decl(declarationNoDanglingGenerics.ts, 28, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +} diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.types b/tests/baselines/reference/declarationNoDanglingGenerics.types new file mode 100644 index 00000000000..c650839be16 --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/declarationNoDanglingGenerics.ts === +const kindCache: { [kind: string]: boolean } = {}; +>kindCache : { [kind: string]: boolean; } +>kind : string +>{} : {} + +function register(kind: string): void | never { +>register : (kind: string) => void +>kind : string + + if (kindCache[kind]) { +>kindCache[kind] : boolean +>kindCache : { [kind: string]: boolean; } +>kind : string + + throw new Error(`Class with kind "${kind}" is already registered.`); +>new Error(`Class with kind "${kind}" is already registered.`) : Error +>Error : ErrorConstructor +>`Class with kind "${kind}" is already registered.` : string +>kind : string + } + kindCache[kind] = true; +>kindCache[kind] = true : true +>kindCache[kind] : boolean +>kindCache : { [kind: string]: boolean; } +>kind : string +>true : true +} + +function ClassFactory(kind: TKind) { +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>TKind : TKind +>kind : TKind +>TKind : TKind + + register(kind); +>register(kind) : void +>register : (kind: string) => void +>kind : TKind + + return class { +>class { static readonly THE_KIND: TKind = kind; readonly kind: TKind = kind; } : typeof (Anonymous class) + + static readonly THE_KIND: TKind = kind; +>THE_KIND : TKind +>TKind : TKind +>kind : TKind + + readonly kind: TKind = kind; +>kind : TKind +>TKind : TKind +>kind : TKind + + }; +} + +class Kinds { +>Kinds : Kinds + + static readonly A = "A"; +>A : "A" +>"A" : "A" + + static readonly B = "B"; +>B : "B" +>"B" : "B" + + static readonly C = "C"; +>C : "C" +>"C" : "C" +} + +export class AKind extends ClassFactory(Kinds.A) { +>AKind : AKind +>ClassFactory(Kinds.A) : ClassFactory<"A">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.A : "A" +>Kinds : typeof Kinds +>A : "A" +} + +export class BKind extends ClassFactory(Kinds.B) { +>BKind : BKind +>ClassFactory(Kinds.B) : ClassFactory<"B">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.B : "B" +>Kinds : typeof Kinds +>B : "B" +} + +export class CKind extends ClassFactory(Kinds.C) { +>CKind : CKind +>ClassFactory(Kinds.C) : ClassFactory<"C">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.C : "C" +>Kinds : typeof Kinds +>C : "C" +} diff --git a/tests/cases/compiler/declarationNoDanglingGenerics.ts b/tests/cases/compiler/declarationNoDanglingGenerics.ts new file mode 100644 index 00000000000..baedcc8a74e --- /dev/null +++ b/tests/cases/compiler/declarationNoDanglingGenerics.ts @@ -0,0 +1,33 @@ +// @declaration: true +const kindCache: { [kind: string]: boolean } = {}; + +function register(kind: string): void | never { + if (kindCache[kind]) { + throw new Error(`Class with kind "${kind}" is already registered.`); + } + kindCache[kind] = true; +} + +function ClassFactory(kind: TKind) { + register(kind); + + return class { + static readonly THE_KIND: TKind = kind; + readonly kind: TKind = kind; + }; +} + +class Kinds { + static readonly A = "A"; + static readonly B = "B"; + static readonly C = "C"; +} + +export class AKind extends ClassFactory(Kinds.A) { +} + +export class BKind extends ClassFactory(Kinds.B) { +} + +export class CKind extends ClassFactory(Kinds.C) { +} \ No newline at end of file