From b4b17f35ecd636ba1f9f689a946591766dd83222 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 28 Dec 2025 10:56:17 -1000 Subject: [PATCH 1/2] Port #62928 --- internal/checker/checker.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/checker/checker.go b/internal/checker/checker.go index f2a212a060..8d19d3eb27 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -18556,6 +18556,9 @@ func findIndexInfo(indexInfos []*IndexInfo, keyType *Type) *IndexInfo { } func (c *Checker) getBaseTypes(t *Type) []*Type { + if t.objectFlags&(ObjectFlagsClassOrInterface|ObjectFlagsReference) == 0 { + return nil + } data := t.AsInterfaceType() if !data.baseTypesResolved { if !c.pushTypeResolution(t, TypeSystemPropertyNameResolvedBaseTypes) { From 1a9eabe4640518ab809638b8efa2be716dee3065 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 28 Dec 2025 10:59:15 -1000 Subject: [PATCH 2/2] Copy regression test --- .../compiler/noCrashOnMixin2.errors.txt | 41 ++++++++++++++ .../compiler/noCrashOnMixin2.symbols | 53 +++++++++++++++++++ .../reference/compiler/noCrashOnMixin2.types | 51 ++++++++++++++++++ .../tests/cases/compiler/noCrashOnMixin2.ts | 28 ++++++++++ 4 files changed, 173 insertions(+) create mode 100644 testdata/baselines/reference/compiler/noCrashOnMixin2.errors.txt create mode 100644 testdata/baselines/reference/compiler/noCrashOnMixin2.symbols create mode 100644 testdata/baselines/reference/compiler/noCrashOnMixin2.types create mode 100644 testdata/tests/cases/compiler/noCrashOnMixin2.ts diff --git a/testdata/baselines/reference/compiler/noCrashOnMixin2.errors.txt b/testdata/baselines/reference/compiler/noCrashOnMixin2.errors.txt new file mode 100644 index 0000000000..d7e28ae49b --- /dev/null +++ b/testdata/baselines/reference/compiler/noCrashOnMixin2.errors.txt @@ -0,0 +1,41 @@ +noCrashOnMixin2.ts(11,33): error TS2370: A rest parameter must be of an array type. +noCrashOnMixin2.ts(11,40): error TS1047: A rest parameter cannot be optional. +noCrashOnMixin2.ts(14,12): error TS2545: A mixin class must have a constructor with a single rest parameter of type 'any[]'. +noCrashOnMixin2.ts(23,9): error TS2674: Constructor of class 'Abstract' is protected and only accessible within the class declaration. + + +==== noCrashOnMixin2.ts (4 errors) ==== + // https://github.com/microsoft/TypeScript/issues/62921 + + class Abstract { + protected constructor() { + } + } + + class Concrete extends Abstract { + } + + type Constructor = new (...args?: any[]) => T; + ~~~~~~~~~~~~~~~ +!!! error TS2370: A rest parameter must be of an array type. + ~ +!!! error TS1047: A rest parameter cannot be optional. + + function Mixin(Base: TBase) { + return class extends Base { + ~~~~~ +!!! error TS2545: A mixin class must have a constructor with a single rest parameter of type 'any[]'. + }; + } + + class Empty { + } + + class CrashTrigger extends Mixin(Empty) { + public trigger() { + new Concrete(); + ~~~~~~~~~~~~~~ +!!! error TS2674: Constructor of class 'Abstract' is protected and only accessible within the class declaration. + } + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/noCrashOnMixin2.symbols b/testdata/baselines/reference/compiler/noCrashOnMixin2.symbols new file mode 100644 index 0000000000..428e2e5de2 --- /dev/null +++ b/testdata/baselines/reference/compiler/noCrashOnMixin2.symbols @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/noCrashOnMixin2.ts] //// + +=== noCrashOnMixin2.ts === +// https://github.com/microsoft/TypeScript/issues/62921 + +class Abstract { +>Abstract : Symbol(Abstract, Decl(noCrashOnMixin2.ts, 0, 0)) + + protected constructor() { + } +} + +class Concrete extends Abstract { +>Concrete : Symbol(Concrete, Decl(noCrashOnMixin2.ts, 5, 1)) +>Abstract : Symbol(Abstract, Decl(noCrashOnMixin2.ts, 0, 0)) +} + +type Constructor = new (...args?: any[]) => T; +>Constructor : Symbol(Constructor, Decl(noCrashOnMixin2.ts, 8, 1)) +>T : Symbol(T, Decl(noCrashOnMixin2.ts, 10, 17)) +>args : Symbol(args, Decl(noCrashOnMixin2.ts, 10, 32)) +>T : Symbol(T, Decl(noCrashOnMixin2.ts, 10, 17)) + +function Mixin(Base: TBase) { +>Mixin : Symbol(Mixin, Decl(noCrashOnMixin2.ts, 10, 54)) +>TBase : Symbol(TBase, Decl(noCrashOnMixin2.ts, 12, 15)) +>Constructor : Symbol(Constructor, Decl(noCrashOnMixin2.ts, 8, 1)) +>Base : Symbol(Base, Decl(noCrashOnMixin2.ts, 12, 42)) +>TBase : Symbol(TBase, Decl(noCrashOnMixin2.ts, 12, 15)) + + return class extends Base { +>Base : Symbol(Base, Decl(noCrashOnMixin2.ts, 12, 42)) + + }; +} + +class Empty { +>Empty : Symbol(Empty, Decl(noCrashOnMixin2.ts, 15, 1)) +} + +class CrashTrigger extends Mixin(Empty) { +>CrashTrigger : Symbol(CrashTrigger, Decl(noCrashOnMixin2.ts, 18, 1)) +>Mixin : Symbol(Mixin, Decl(noCrashOnMixin2.ts, 10, 54)) +>Empty : Symbol(Empty, Decl(noCrashOnMixin2.ts, 15, 1)) + + public trigger() { +>trigger : Symbol(CrashTrigger.trigger, Decl(noCrashOnMixin2.ts, 20, 41)) + + new Concrete(); +>Concrete : Symbol(Concrete, Decl(noCrashOnMixin2.ts, 5, 1)) + } +} + diff --git a/testdata/baselines/reference/compiler/noCrashOnMixin2.types b/testdata/baselines/reference/compiler/noCrashOnMixin2.types new file mode 100644 index 0000000000..e7505ee15e --- /dev/null +++ b/testdata/baselines/reference/compiler/noCrashOnMixin2.types @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/noCrashOnMixin2.ts] //// + +=== noCrashOnMixin2.ts === +// https://github.com/microsoft/TypeScript/issues/62921 + +class Abstract { +>Abstract : Abstract + + protected constructor() { + } +} + +class Concrete extends Abstract { +>Concrete : Concrete +>Abstract : Abstract +} + +type Constructor = new (...args?: any[]) => T; +>Constructor : Constructor +>args : any[] | undefined + +function Mixin(Base: TBase) { +>Mixin : >(Base: TBase) => { new (...args?: any[] | undefined): (Anonymous class); prototype: Mixin.(Anonymous class); } & TBase +>Base : TBase + + return class extends Base { +>class extends Base { } : { new (...args?: any[] | undefined): (Anonymous class); prototype: Mixin.(Anonymous class); } & TBase +>Base : {} + + }; +} + +class Empty { +>Empty : Empty +} + +class CrashTrigger extends Mixin(Empty) { +>CrashTrigger : CrashTrigger +>Mixin(Empty) : Mixin.(Anonymous class) +>Mixin : >(Base: TBase) => { new (...args?: any[] | undefined): (Anonymous class); prototype: Mixin.(Anonymous class); } & TBase +>Empty : typeof Empty + + public trigger() { +>trigger : () => void + + new Concrete(); +>new Concrete() : Concrete +>Concrete : typeof Concrete + } +} + diff --git a/testdata/tests/cases/compiler/noCrashOnMixin2.ts b/testdata/tests/cases/compiler/noCrashOnMixin2.ts new file mode 100644 index 0000000000..f6ddccf948 --- /dev/null +++ b/testdata/tests/cases/compiler/noCrashOnMixin2.ts @@ -0,0 +1,28 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62921 + +class Abstract { + protected constructor() { + } +} + +class Concrete extends Abstract { +} + +type Constructor = new (...args?: any[]) => T; + +function Mixin(Base: TBase) { + return class extends Base { + }; +} + +class Empty { +} + +class CrashTrigger extends Mixin(Empty) { + public trigger() { + new Concrete(); + } +}