-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow local class declarations to be returned as mixins (#22807)
- Loading branch information
Showing
5 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
//// [declarationEmitLocalClassDeclarationMixin.ts] | ||
interface Constructor<C> { new (...args: any[]): C; } | ||
|
||
function mixin<B extends Constructor<{}>>(Base: B) { | ||
class PrivateMixed extends Base { | ||
bar = 2; | ||
} | ||
return PrivateMixed; | ||
} | ||
|
||
export class Unmixed { | ||
foo = 1; | ||
} | ||
|
||
export const Mixed = mixin(Unmixed); | ||
|
||
function Filter<C extends Constructor<{}>>(ctor: C) { | ||
abstract class FilterMixin extends ctor { | ||
abstract match(path: string): boolean; | ||
// other concrete methods, fields, constructor | ||
thing = 12; | ||
} | ||
return FilterMixin; | ||
} | ||
|
||
export class FilteredThing extends Filter(Unmixed) { | ||
match(path: string) { | ||
return false; | ||
} | ||
} | ||
|
||
|
||
//// [declarationEmitLocalClassDeclarationMixin.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; | ||
function mixin(Base) { | ||
var PrivateMixed = /** @class */ (function (_super) { | ||
__extends(PrivateMixed, _super); | ||
function PrivateMixed() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.bar = 2; | ||
return _this; | ||
} | ||
return PrivateMixed; | ||
}(Base)); | ||
return PrivateMixed; | ||
} | ||
var Unmixed = /** @class */ (function () { | ||
function Unmixed() { | ||
this.foo = 1; | ||
} | ||
return Unmixed; | ||
}()); | ||
exports.Unmixed = Unmixed; | ||
exports.Mixed = mixin(Unmixed); | ||
function Filter(ctor) { | ||
var FilterMixin = /** @class */ (function (_super) { | ||
__extends(FilterMixin, _super); | ||
function FilterMixin() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
// other concrete methods, fields, constructor | ||
_this.thing = 12; | ||
return _this; | ||
} | ||
return FilterMixin; | ||
}(ctor)); | ||
return FilterMixin; | ||
} | ||
var FilteredThing = /** @class */ (function (_super) { | ||
__extends(FilteredThing, _super); | ||
function FilteredThing() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
FilteredThing.prototype.match = function (path) { | ||
return false; | ||
}; | ||
return FilteredThing; | ||
}(Filter(Unmixed))); | ||
exports.FilteredThing = FilteredThing; | ||
|
||
|
||
//// [declarationEmitLocalClassDeclarationMixin.d.ts] | ||
export declare class Unmixed { | ||
foo: number; | ||
} | ||
export declare const Mixed: { | ||
new (...args: any[]): { | ||
bar: number; | ||
}; | ||
} & typeof Unmixed; | ||
declare const FilteredThing_base: { | ||
new (...args: any[]): { | ||
match(path: string): boolean; | ||
thing: number; | ||
}; | ||
} & typeof Unmixed; | ||
export declare class FilteredThing extends FilteredThing_base { | ||
match(path: string): boolean; | ||
} |
73 changes: 73 additions & 0 deletions
73
tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.symbols
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
=== tests/cases/compiler/declarationEmitLocalClassDeclarationMixin.ts === | ||
interface Constructor<C> { new (...args: any[]): C; } | ||
>Constructor : Symbol(Constructor, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 0)) | ||
>C : Symbol(C, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 22)) | ||
>args : Symbol(args, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 32)) | ||
>C : Symbol(C, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 22)) | ||
|
||
function mixin<B extends Constructor<{}>>(Base: B) { | ||
>mixin : Symbol(mixin, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 53)) | ||
>B : Symbol(B, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 15)) | ||
>Constructor : Symbol(Constructor, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 0)) | ||
>Base : Symbol(Base, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 42)) | ||
>B : Symbol(B, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 15)) | ||
|
||
class PrivateMixed extends Base { | ||
>PrivateMixed : Symbol(PrivateMixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 52)) | ||
>Base : Symbol(Base, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 42)) | ||
|
||
bar = 2; | ||
>bar : Symbol(PrivateMixed.bar, Decl(declarationEmitLocalClassDeclarationMixin.ts, 3, 37)) | ||
} | ||
return PrivateMixed; | ||
>PrivateMixed : Symbol(PrivateMixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 2, 52)) | ||
} | ||
|
||
export class Unmixed { | ||
>Unmixed : Symbol(Unmixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 7, 1)) | ||
|
||
foo = 1; | ||
>foo : Symbol(Unmixed.foo, Decl(declarationEmitLocalClassDeclarationMixin.ts, 9, 22)) | ||
} | ||
|
||
export const Mixed = mixin(Unmixed); | ||
>Mixed : Symbol(Mixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 13, 12)) | ||
>mixin : Symbol(mixin, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 53)) | ||
>Unmixed : Symbol(Unmixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 7, 1)) | ||
|
||
function Filter<C extends Constructor<{}>>(ctor: C) { | ||
>Filter : Symbol(Filter, Decl(declarationEmitLocalClassDeclarationMixin.ts, 13, 36)) | ||
>C : Symbol(C, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 16)) | ||
>Constructor : Symbol(Constructor, Decl(declarationEmitLocalClassDeclarationMixin.ts, 0, 0)) | ||
>ctor : Symbol(ctor, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 43)) | ||
>C : Symbol(C, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 16)) | ||
|
||
abstract class FilterMixin extends ctor { | ||
>FilterMixin : Symbol(FilterMixin, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 53)) | ||
>ctor : Symbol(ctor, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 43)) | ||
|
||
abstract match(path: string): boolean; | ||
>match : Symbol(FilterMixin.match, Decl(declarationEmitLocalClassDeclarationMixin.ts, 16, 45)) | ||
>path : Symbol(path, Decl(declarationEmitLocalClassDeclarationMixin.ts, 17, 23)) | ||
|
||
// other concrete methods, fields, constructor | ||
thing = 12; | ||
>thing : Symbol(FilterMixin.thing, Decl(declarationEmitLocalClassDeclarationMixin.ts, 17, 46)) | ||
} | ||
return FilterMixin; | ||
>FilterMixin : Symbol(FilterMixin, Decl(declarationEmitLocalClassDeclarationMixin.ts, 15, 53)) | ||
} | ||
|
||
export class FilteredThing extends Filter(Unmixed) { | ||
>FilteredThing : Symbol(FilteredThing, Decl(declarationEmitLocalClassDeclarationMixin.ts, 22, 1)) | ||
>Filter : Symbol(Filter, Decl(declarationEmitLocalClassDeclarationMixin.ts, 13, 36)) | ||
>Unmixed : Symbol(Unmixed, Decl(declarationEmitLocalClassDeclarationMixin.ts, 7, 1)) | ||
|
||
match(path: string) { | ||
>match : Symbol(FilteredThing.match, Decl(declarationEmitLocalClassDeclarationMixin.ts, 24, 52)) | ||
>path : Symbol(path, Decl(declarationEmitLocalClassDeclarationMixin.ts, 25, 10)) | ||
|
||
return false; | ||
} | ||
} | ||
|
79 changes: 79 additions & 0 deletions
79
tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
=== tests/cases/compiler/declarationEmitLocalClassDeclarationMixin.ts === | ||
interface Constructor<C> { new (...args: any[]): C; } | ||
>Constructor : Constructor<C> | ||
>C : C | ||
>args : any[] | ||
>C : C | ||
|
||
function mixin<B extends Constructor<{}>>(Base: B) { | ||
>mixin : <B extends Constructor<{}>>(Base: B) => { new (...args: any[]): PrivateMixed; prototype: mixin<any>.PrivateMixed; } & B | ||
>B : B | ||
>Constructor : Constructor<C> | ||
>Base : B | ||
>B : B | ||
|
||
class PrivateMixed extends Base { | ||
>PrivateMixed : PrivateMixed | ||
>Base : {} | ||
|
||
bar = 2; | ||
>bar : number | ||
>2 : 2 | ||
} | ||
return PrivateMixed; | ||
>PrivateMixed : { new (...args: any[]): PrivateMixed; prototype: mixin<any>.PrivateMixed; } & B | ||
} | ||
|
||
export class Unmixed { | ||
>Unmixed : Unmixed | ||
|
||
foo = 1; | ||
>foo : number | ||
>1 : 1 | ||
} | ||
|
||
export const Mixed = mixin(Unmixed); | ||
>Mixed : { new (...args: any[]): mixin<typeof Unmixed>.PrivateMixed; prototype: mixin<any>.PrivateMixed; } & typeof Unmixed | ||
>mixin(Unmixed) : { new (...args: any[]): mixin<typeof Unmixed>.PrivateMixed; prototype: mixin<any>.PrivateMixed; } & typeof Unmixed | ||
>mixin : <B extends Constructor<{}>>(Base: B) => { new (...args: any[]): PrivateMixed; prototype: mixin<any>.PrivateMixed; } & B | ||
>Unmixed : typeof Unmixed | ||
|
||
function Filter<C extends Constructor<{}>>(ctor: C) { | ||
>Filter : <C extends Constructor<{}>>(ctor: C) => { new (...args: any[]): FilterMixin; prototype: Filter<any>.FilterMixin; } & C | ||
>C : C | ||
>Constructor : Constructor<C> | ||
>ctor : C | ||
>C : C | ||
|
||
abstract class FilterMixin extends ctor { | ||
>FilterMixin : FilterMixin | ||
>ctor : {} | ||
|
||
abstract match(path: string): boolean; | ||
>match : (path: string) => boolean | ||
>path : string | ||
|
||
// other concrete methods, fields, constructor | ||
thing = 12; | ||
>thing : number | ||
>12 : 12 | ||
} | ||
return FilterMixin; | ||
>FilterMixin : { new (...args: any[]): FilterMixin; prototype: Filter<any>.FilterMixin; } & C | ||
} | ||
|
||
export class FilteredThing extends Filter(Unmixed) { | ||
>FilteredThing : FilteredThing | ||
>Filter(Unmixed) : Filter<typeof Unmixed>.FilterMixin & Unmixed | ||
>Filter : <C extends Constructor<{}>>(ctor: C) => { new (...args: any[]): FilterMixin; prototype: Filter<any>.FilterMixin; } & C | ||
>Unmixed : typeof Unmixed | ||
|
||
match(path: string) { | ||
>match : (path: string) => boolean | ||
>path : string | ||
|
||
return false; | ||
>false : false | ||
} | ||
} | ||
|
30 changes: 30 additions & 0 deletions
30
tests/cases/compiler/declarationEmitLocalClassDeclarationMixin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// @declaration: true | ||
interface Constructor<C> { new (...args: any[]): C; } | ||
|
||
function mixin<B extends Constructor<{}>>(Base: B) { | ||
class PrivateMixed extends Base { | ||
bar = 2; | ||
} | ||
return PrivateMixed; | ||
} | ||
|
||
export class Unmixed { | ||
foo = 1; | ||
} | ||
|
||
export const Mixed = mixin(Unmixed); | ||
|
||
function Filter<C extends Constructor<{}>>(ctor: C) { | ||
abstract class FilterMixin extends ctor { | ||
abstract match(path: string): boolean; | ||
// other concrete methods, fields, constructor | ||
thing = 12; | ||
} | ||
return FilterMixin; | ||
} | ||
|
||
export class FilteredThing extends Filter(Unmixed) { | ||
match(path: string) { | ||
return false; | ||
} | ||
} |