Merge pull request #13743 from Microsoft/mixinClasses

Mixin classes
This commit is contained in:
Anders Hejlsberg 2017-01-30 12:47:21 -10:00 committed by GitHub
commit f32f95ae23
14 changed files with 2298 additions and 14 deletions

View file

@ -2465,7 +2465,8 @@ namespace ts {
const symbol = type.symbol;
if (symbol) {
// Always use 'typeof T' for type of class, enum, and module objects
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) ||
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) {
writeTypeOfSymbol(type, flags);
}
else if (shouldWriteTypeOfFunctionSymbol()) {
@ -3639,6 +3640,11 @@ namespace ts {
return links.type;
}
function getBaseTypeVariableOfClass(symbol: Symbol) {
const baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : undefined;
}
function getTypeOfFuncClassEnumModule(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
if (!links.type) {
@ -3647,8 +3653,13 @@ namespace ts {
}
else {
const type = createObjectType(ObjectFlags.Anonymous, symbol);
links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ?
includeFalsyTypes(type, TypeFlags.Undefined) : type;
if (symbol.flags & SymbolFlags.Class) {
const baseTypeVariable = getBaseTypeVariableOfClass(symbol);
links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
}
else {
links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
}
}
}
return links.type;
@ -3812,8 +3823,26 @@ namespace ts {
return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
}
// A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
// rest parameter of type any[].
function isMixinConstructorType(type: Type) {
const signatures = getSignaturesOfType(type, SignatureKind.Construct);
if (signatures.length === 1) {
const s = signatures[0];
return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType;
}
return false;
}
function isConstructorType(type: Type): boolean {
return isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0;
if (isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0) {
return true;
}
if (type.flags & TypeFlags.TypeVariable) {
const constraint = getBaseConstraintOfType(<TypeVariable>type);
return isValidBaseType(constraint) && isMixinConstructorType(constraint);
}
return false;
}
function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments {
@ -3892,7 +3921,7 @@ namespace ts {
function resolveBaseTypesOfClass(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
const baseConstructorType = <ObjectType>getBaseConstructorTypeOfClass(type);
const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
return;
}
@ -4542,16 +4571,47 @@ namespace ts {
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
}
function includeMixinType(type: Type, types: Type[], index: number): Type {
const mixedTypes: Type[] = [];
for (let i = 0; i < types.length; i++) {
if (i === index) {
mixedTypes.push(type);
}
else if (isMixinConstructorType(types[i])) {
mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0]));
}
}
return getIntersectionType(mixedTypes);
}
function resolveIntersectionTypeMembers(type: IntersectionType) {
// The members and properties collections are empty for intersection types. To get all properties of an
// intersection type use getPropertiesOfType (only the language service uses this).
let callSignatures: Signature[] = emptyArray;
let constructSignatures: Signature[] = emptyArray;
let stringIndexInfo: IndexInfo = undefined;
let numberIndexInfo: IndexInfo = undefined;
for (const t of type.types) {
let stringIndexInfo: IndexInfo;
let numberIndexInfo: IndexInfo;
const types = type.types;
const mixinCount = countWhere(types, isMixinConstructorType);
for (let i = 0; i < types.length; i++) {
const t = type.types[i];
// When an intersection type contains mixin constructor types, the construct signatures from
// those types are discarded and their return types are mixed into the return types of all
// other construct signatures in the intersection type. For example, the intersection type
// '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
// 'new(s: string) => A & B'.
if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) {
let signatures = getSignaturesOfType(t, SignatureKind.Construct);
if (signatures.length && mixinCount > 0) {
signatures = map(signatures, s => {
const clone = cloneSignature(s);
clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i);
return clone;
});
}
constructSignatures = concatenate(constructSignatures, signatures);
}
callSignatures = concatenate(callSignatures, getSignaturesOfType(t, SignatureKind.Call));
constructSignatures = concatenate(constructSignatures, getSignaturesOfType(t, SignatureKind.Construct));
stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String));
numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number));
}
@ -4593,7 +4653,7 @@ namespace ts {
constructSignatures = getDefaultConstructSignatures(classType);
}
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
members = createSymbolTable(getNamedMembers(members));
addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
}
@ -4890,6 +4950,7 @@ namespace ts {
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol {
const types = containingType.types;
const excludeModifiers = containingType.flags & TypeFlags.Union ? ModifierFlags.Private | ModifierFlags.Protected : 0;
let props: Symbol[];
// Flags we want to propagate to the result if they exist in all source symbols
let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None;
@ -4899,7 +4960,7 @@ namespace ts {
const type = getApparentType(current);
if (type !== unknownType) {
const prop = getPropertyOfType(type, name);
if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))) {
if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & excludeModifiers)) {
commonFlags &= prop.flags;
if (!props) {
props = [prop];
@ -6965,9 +7026,12 @@ namespace ts {
result.properties = resolved.properties;
result.callSignatures = emptyArray;
result.constructSignatures = emptyArray;
type = result;
return result;
}
}
else if (type.flags & TypeFlags.Intersection) {
return getIntersectionType(map((<IntersectionType>type).types, getTypeWithoutSignatures));
}
return type;
}
@ -18390,7 +18454,8 @@ namespace ts {
const baseTypes = getBaseTypes(type);
if (baseTypes.length && produceDiagnostics) {
const baseType = baseTypes[0];
const staticBaseType = getBaseConstructorTypeOfClass(type);
const baseConstructorType = getBaseConstructorTypeOfClass(type);
const staticBaseType = getApparentType(baseConstructorType);
checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
checkSourceElement(baseTypeNode.expression);
if (baseTypeNode.typeArguments) {
@ -18404,6 +18469,9 @@ namespace ts {
checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1);
checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node,
Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) {
error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
}
if (baseType.symbol && baseType.symbol.valueDeclaration &&
!isInAmbientContext(baseType.symbol.valueDeclaration) &&
@ -18413,7 +18481,7 @@ namespace ts {
}
}
if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class)) {
if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) {
// When the static base type is a "class-like" constructor function (but not actually a class), we verify
// that all instantiated base constructor signatures return the same type. We can simply compare the type
// references (as opposed to checking the structure of the types) because elsewhere we have already checked

View file

@ -1783,6 +1783,10 @@
"category": "Error",
"code": 2544
},
"A mixin class must have a constructor with a single rest parameter of type 'any[]'.": {
"category": "Error",
"code": 2545
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600

View file

@ -0,0 +1,183 @@
//// [mixinClassesAnnotated.ts]
type Constructor<T> = new(...args: any[]) => T;
class Base {
constructor(public x: number, public y: number) {}
}
class Derived extends Base {
constructor(x: number, y: number, public z: number) {
super(x, y);
}
}
interface Printable {
print(): void;
}
const Printable = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
interface Tagged {
_tag: string;
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
class C extends superClass {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "hello";
}
}
return C;
}
const Thing1 = Tagged(Derived);
const Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
const thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
const thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
class Thing3 extends Thing2 {
constructor(tag: string) {
super(10, 20, 30);
this._tag = tag;
}
test() {
this.print();
}
}
//// [mixinClassesAnnotated.js]
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 __());
};
})();
var Base = (function () {
function Base(x, y) {
this.x = x;
this.y = y;
}
return Base;
}());
var Derived = (function (_super) {
__extends(Derived, _super);
function Derived(x, y, z) {
var _this = _super.call(this, x, y) || this;
_this.z = z;
return _this;
}
return Derived;
}(Base));
var Printable = function (superClass) { return _a = (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
class_1.prototype.print = function () {
var output = this.x + "," + this.y;
};
return class_1;
}(superClass)),
_a.message = "hello",
_a; var _a; };
function Tagged(superClass) {
var C = (function (_super) {
__extends(C, _super);
function C() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _this = _super.apply(this, args) || this;
_this._tag = "hello";
return _this;
}
return C;
}(superClass));
return C;
}
var Thing1 = Tagged(Derived);
var Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
var thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
var thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
var Thing3 = (function (_super) {
__extends(Thing3, _super);
function Thing3(tag) {
var _this = _super.call(this, 10, 20, 30) || this;
_this._tag = tag;
return _this;
}
Thing3.prototype.test = function () {
this.print();
};
return Thing3;
}(Thing2));
//// [mixinClassesAnnotated.d.ts]
declare type Constructor<T> = new (...args: any[]) => T;
declare class Base {
x: number;
y: number;
constructor(x: number, y: number);
}
declare class Derived extends Base {
z: number;
constructor(x: number, y: number, z: number);
}
interface Printable {
print(): void;
}
declare const Printable: <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & {
message: string;
} & T;
interface Tagged {
_tag: string;
}
declare function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T;
declare const Thing1: Constructor<Tagged> & typeof Derived;
declare const Thing2: Constructor<Tagged> & Constructor<Printable> & {
message: string;
} & typeof Derived;
declare function f1(): void;
declare function f2(): void;
declare class Thing3 extends Thing2 {
constructor(tag: string);
test(): void;
}

View file

@ -0,0 +1,193 @@
=== tests/cases/conformance/classes/mixinClassesAnnotated.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17))
>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 1, 26))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17))
class Base {
>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47))
constructor(public x: number, public y: number) {}
>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33))
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1))
>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47))
constructor(x: number, y: number, public z: number) {
>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16))
>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26))
>z : Symbol(Derived.z, Decl(mixinClassesAnnotated.ts, 8, 37))
super(x, y);
>super : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47))
>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16))
>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26))
}
}
interface Printable {
>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5))
print(): void;
>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21))
}
const Printable = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0))
>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47))
>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0))
>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5))
>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19))
class extends superClass {
>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48))
static message = "hello";
>message : Symbol((Anonymous class).message, Decl(mixinClassesAnnotated.ts, 18, 30))
print() {
>print : Symbol((Anonymous class).print, Decl(mixinClassesAnnotated.ts, 19, 33))
const output = this.x + "," + this.y;
>output : Symbol(output, Decl(mixinClassesAnnotated.ts, 21, 17))
>this.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115))
>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
>this.y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33))
>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115))
>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33))
}
}
interface Tagged {
>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1))
_tag: string;
>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0))
>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0))
>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1))
>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16))
class C extends superClass {
>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84))
>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43))
_tag: string;
>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32))
constructor(...args: any[]) {
>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20))
super(...args);
>super : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16))
>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20))
this._tag = "hello";
>this._tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32))
>this : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84))
>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32))
}
}
return C;
>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84))
}
const Thing1 = Tagged(Derived);
>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5))
>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1))
>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1))
const Thing2 = Tagged(Printable(Derived));
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5))
>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1))
>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5))
>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1))
Thing2.message;
>Thing2.message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5))
>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90))
function f1() {
>f1 : Symbol(f1, Decl(mixinClassesAnnotated.ts, 42, 15))
const thing = new Thing1(1, 2, 3);
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9))
>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5))
thing.x;
>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9))
>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
thing._tag;
>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9))
>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
}
function f2() {
>f2 : Symbol(f2, Decl(mixinClassesAnnotated.ts, 48, 1))
const thing = new Thing2(1, 2, 3);
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5))
thing.x;
>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9))
>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16))
thing._tag;
>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9))
>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
thing.print();
>thing.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21))
>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9))
>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21))
}
class Thing3 extends Thing2 {
>Thing3 : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5))
constructor(tag: string) {
>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16))
super(10, 20, 30);
this._tag = tag;
>this._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1))
>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18))
>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16))
}
test() {
>test : Symbol(Thing3.test, Decl(mixinClassesAnnotated.ts, 61, 5))
this.print();
>this.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21))
>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1))
>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21))
}
}

View file

@ -0,0 +1,224 @@
=== tests/cases/conformance/classes/mixinClassesAnnotated.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Constructor<T>
>T : T
>args : any[]
>T : T
class Base {
>Base : Base
constructor(public x: number, public y: number) {}
>x : number
>y : number
}
class Derived extends Base {
>Derived : Derived
>Base : Base
constructor(x: number, y: number, public z: number) {
>x : number
>y : number
>z : number
super(x, y);
>super(x, y) : void
>super : typeof Base
>x : number
>y : number
}
}
interface Printable {
>Printable : Printable
print(): void;
>print : () => void
}
const Printable = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
>Printable : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
><T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
>T : T
>Constructor : Constructor<T>
>Base : Base
>superClass : T
>T : T
>Constructor : Constructor<T>
>Printable : Printable
>message : string
>T : T
class extends superClass {
>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>superClass : Base
static message = "hello";
>message : string
>"hello" : "hello"
print() {
>print : () => void
const output = this.x + "," + this.y;
>output : string
>this.x + "," + this.y : string
>this.x + "," : string
>this.x : number
>this : this
>x : number
>"," : ","
>this.y : number
>this : this
>y : number
}
}
interface Tagged {
>Tagged : Tagged
_tag: string;
>_tag : string
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>T : T
>Constructor : Constructor<T>
>superClass : T
>T : T
>Constructor : Constructor<T>
>Tagged : Tagged
>T : T
class C extends superClass {
>C : C
>superClass : {}
_tag: string;
>_tag : string
constructor(...args: any[]) {
>args : any[]
super(...args);
>super(...args) : void
>super : T
>...args : any
>args : any[]
this._tag = "hello";
>this._tag = "hello" : "hello"
>this._tag : string
>this : this
>_tag : string
>"hello" : "hello"
}
}
return C;
>C : { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
}
const Thing1 = Tagged(Derived);
>Thing1 : Constructor<Tagged> & typeof Derived
>Tagged(Derived) : Constructor<Tagged> & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>Derived : typeof Derived
const Thing2 = Tagged(Printable(Derived));
>Thing2 : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>Tagged(Printable(Derived)) : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>Printable(Derived) : Constructor<Printable> & { message: string; } & typeof Derived
>Printable : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
>Derived : typeof Derived
Thing2.message;
>Thing2.message : string
>Thing2 : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>message : string
function f1() {
>f1 : () => void
const thing = new Thing1(1, 2, 3);
>thing : Tagged & Derived
>new Thing1(1, 2, 3) : Tagged & Derived
>Thing1 : Constructor<Tagged> & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged & Derived
>_tag : string
}
function f2() {
>f2 : () => void
const thing = new Thing2(1, 2, 3);
>thing : Tagged & Printable & Derived
>new Thing2(1, 2, 3) : Tagged & Printable & Derived
>Thing2 : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged & Printable & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged & Printable & Derived
>_tag : string
thing.print();
>thing.print() : void
>thing.print : () => void
>thing : Tagged & Printable & Derived
>print : () => void
}
class Thing3 extends Thing2 {
>Thing3 : Thing3
>Thing2 : Tagged & Printable & Derived
constructor(tag: string) {
>tag : string
super(10, 20, 30);
>super(10, 20, 30) : void
>super : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>10 : 10
>20 : 20
>30 : 30
this._tag = tag;
>this._tag = tag : string
>this._tag : string
>this : this
>_tag : string
>tag : string
}
test() {
>test : () => void
this.print();
>this.print() : void
>this.print : () => void
>this : this
>print : () => void
}
}

View file

@ -0,0 +1,140 @@
//// [mixinClassesAnonymous.ts]
type Constructor<T> = new(...args: any[]) => T;
class Base {
constructor(public x: number, public y: number) {}
}
class Derived extends Base {
constructor(x: number, y: number, public z: number) {
super(x, y);
}
}
const Printable = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
function Tagged<T extends Constructor<{}>>(superClass: T) {
class C extends superClass {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "hello";
}
}
return C;
}
const Thing1 = Tagged(Derived);
const Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
const thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
const thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
class Thing3 extends Thing2 {
constructor(tag: string) {
super(10, 20, 30);
this._tag = tag;
}
test() {
this.print();
}
}
//// [mixinClassesAnonymous.js]
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 __());
};
})();
var Base = (function () {
function Base(x, y) {
this.x = x;
this.y = y;
}
return Base;
}());
var Derived = (function (_super) {
__extends(Derived, _super);
function Derived(x, y, z) {
var _this = _super.call(this, x, y) || this;
_this.z = z;
return _this;
}
return Derived;
}(Base));
var Printable = function (superClass) { return _a = (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
class_1.prototype.print = function () {
var output = this.x + "," + this.y;
};
return class_1;
}(superClass)),
_a.message = "hello",
_a; var _a; };
function Tagged(superClass) {
var C = (function (_super) {
__extends(C, _super);
function C() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _this = _super.apply(this, args) || this;
_this._tag = "hello";
return _this;
}
return C;
}(superClass));
return C;
}
var Thing1 = Tagged(Derived);
var Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
var thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
var thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
var Thing3 = (function (_super) {
__extends(Thing3, _super);
function Thing3(tag) {
var _this = _super.call(this, 10, 20, 30) || this;
_this._tag = tag;
return _this;
}
Thing3.prototype.test = function () {
this.print();
};
return Thing3;
}(Thing2));

View file

@ -0,0 +1,169 @@
=== tests/cases/conformance/classes/mixinClassesAnonymous.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17))
>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 0, 26))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17))
class Base {
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47))
constructor(public x: number, public y: number) {}
>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33))
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1))
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47))
constructor(x: number, y: number, public z: number) {
>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16))
>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26))
>z : Symbol(Derived.z, Decl(mixinClassesAnonymous.ts, 7, 37))
super(x, y);
>super : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47))
>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16))
>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26))
}
}
const Printable = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0))
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47))
>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19))
>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48))
static message = "hello";
>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92))
print() {
>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29))
const output = this.x + "," + this.y;
>output : Symbol(output, Decl(mixinClassesAnonymous.ts, 15, 13))
>this.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65))
>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
>this.y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33))
>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65))
>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33))
}
}
function Tagged<T extends Constructor<{}>>(superClass: T) {
>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0))
>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43))
>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16))
class C extends superClass {
>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59))
>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43))
_tag: string;
>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
constructor(...args: any[]) {
>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20))
super(...args);
>super : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16))
>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20))
this._tag = "hello";
>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
>this : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59))
>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
}
}
return C;
>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59))
}
const Thing1 = Tagged(Derived);
>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5))
>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1))
>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1))
const Thing2 = Tagged(Printable(Derived));
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5))
>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1))
>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5))
>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1))
Thing2.message;
>Thing2.message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5))
>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92))
function f1() {
>f1 : Symbol(f1, Decl(mixinClassesAnonymous.ts, 32, 15))
const thing = new Thing1(1, 2, 3);
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9))
>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5))
thing.x;
>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9))
>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
thing._tag;
>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9))
>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
}
function f2() {
>f2 : Symbol(f2, Decl(mixinClassesAnonymous.ts, 38, 1))
const thing = new Thing2(1, 2, 3);
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5))
thing.x;
>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9))
>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16))
thing._tag;
>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9))
>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
thing.print();
>thing.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29))
>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9))
>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29))
}
class Thing3 extends Thing2 {
>Thing3 : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1))
>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5))
constructor(tag: string) {
>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16))
super(10, 20, 30);
this._tag = tag;
>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1))
>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32))
>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16))
}
test() {
>test : Symbol(Thing3.test, Decl(mixinClassesAnonymous.ts, 51, 5))
this.print();
>this.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29))
>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1))
>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29))
}
}

View file

@ -0,0 +1,200 @@
=== tests/cases/conformance/classes/mixinClassesAnonymous.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Constructor<T>
>T : T
>args : any[]
>T : T
class Base {
>Base : Base
constructor(public x: number, public y: number) {}
>x : number
>y : number
}
class Derived extends Base {
>Derived : Derived
>Base : Base
constructor(x: number, y: number, public z: number) {
>x : number
>y : number
>z : number
super(x, y);
>super(x, y) : void
>super : typeof Base
>x : number
>y : number
}
}
const Printable = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
>Printable : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
><T extends Constructor<Base>>(superClass: T) => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>T : T
>Constructor : Constructor<T>
>Base : Base
>superClass : T
>T : T
>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>superClass : Base
static message = "hello";
>message : string
>"hello" : "hello"
print() {
>print : () => void
const output = this.x + "," + this.y;
>output : string
>this.x + "," + this.y : string
>this.x + "," : string
>this.x : number
>this : this
>x : number
>"," : ","
>this.y : number
>this : this
>y : number
}
}
function Tagged<T extends Constructor<{}>>(superClass: T) {
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>T : T
>Constructor : Constructor<T>
>superClass : T
>T : T
class C extends superClass {
>C : C
>superClass : {}
_tag: string;
>_tag : string
constructor(...args: any[]) {
>args : any[]
super(...args);
>super(...args) : void
>super : T
>...args : any
>args : any[]
this._tag = "hello";
>this._tag = "hello" : "hello"
>this._tag : string
>this : this
>_tag : string
>"hello" : "hello"
}
}
return C;
>C : { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
}
const Thing1 = Tagged(Derived);
>Thing1 : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>Tagged(Derived) : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>Derived : typeof Derived
const Thing2 = Tagged(Printable(Derived));
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Tagged(Printable(Derived)) : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>Printable(Derived) : { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Printable : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>Derived : typeof Derived
Thing2.message;
>Thing2.message : string
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>message : string
function f1() {
>f1 : () => void
const thing = new Thing1(1, 2, 3);
>thing : Tagged<typeof Derived>.C & Derived
>new Thing1(1, 2, 3) : Tagged<typeof Derived>.C & Derived
>Thing1 : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged<typeof Derived>.C & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged<typeof Derived>.C & Derived
>_tag : string
}
function f2() {
>f2 : () => void
const thing = new Thing2(1, 2, 3);
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>new Thing2(1, 2, 3) : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>_tag : string
thing.print();
>thing.print() : void
>thing.print : () => void
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>print : () => void
}
class Thing3 extends Thing2 {
>Thing3 : Thing3
>Thing2 : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
constructor(tag: string) {
>tag : string
super(10, 20, 30);
>super(10, 20, 30) : void
>super : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>10 : 10
>20 : 20
>30 : 30
this._tag = tag;
>this._tag = tag : string
>this._tag : string
>this : this
>_tag : string
>tag : string
}
test() {
>test : () => void
this.print();
>this.print() : void
>this.print : () => void
>this : this
>print : () => void
}
}

View file

@ -0,0 +1,220 @@
//// [mixinClassesMembers.ts]
declare class C1 {
public a: number;
protected b: number;
private c: number;
constructor(s: string);
constructor(n: number);
}
declare class M1 {
constructor(...args: any[]);
p: number;
static p: number;
}
declare class M2 {
constructor(...args: any[]);
f(): number;
static f(): number;
}
declare const Mixed1: typeof M1 & typeof C1;
declare const Mixed2: typeof C1 & typeof M1;
declare const Mixed3: typeof M2 & typeof M1 & typeof C1;
declare const Mixed4: typeof C1 & typeof M1 & typeof M2;
declare const Mixed5: typeof M1 & typeof M2;
function f1() {
let x1 = new Mixed1("hello");
let x2 = new Mixed1(42);
let x3 = new Mixed2("hello");
let x4 = new Mixed2(42);
let x5 = new Mixed3("hello");
let x6 = new Mixed3(42);
let x7 = new Mixed4("hello");
let x8 = new Mixed4(42);
let x9 = new Mixed5();
}
function f2() {
let x = new Mixed1("hello");
x.a;
x.p;
Mixed1.p;
}
function f3() {
let x = new Mixed2("hello");
x.a;
x.p;
Mixed2.p;
}
function f4() {
let x = new Mixed3("hello");
x.a;
x.p;
x.f();
Mixed3.p;
Mixed3.f();
}
function f5() {
let x = new Mixed4("hello");
x.a;
x.p;
x.f();
Mixed4.p;
Mixed4.f();
}
function f6() {
let x = new Mixed5();
x.p;
x.f();
Mixed5.p;
Mixed5.f();
}
class C2 extends Mixed1 {
constructor() {
super("hello");
this.a;
this.b;
this.p;
}
}
class C3 extends Mixed3 {
constructor() {
super(42);
this.a;
this.b;
this.p;
this.f();
}
f() { return super.f(); }
}
//// [mixinClassesMembers.js]
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 __());
};
})();
function f1() {
var x1 = new Mixed1("hello");
var x2 = new Mixed1(42);
var x3 = new Mixed2("hello");
var x4 = new Mixed2(42);
var x5 = new Mixed3("hello");
var x6 = new Mixed3(42);
var x7 = new Mixed4("hello");
var x8 = new Mixed4(42);
var x9 = new Mixed5();
}
function f2() {
var x = new Mixed1("hello");
x.a;
x.p;
Mixed1.p;
}
function f3() {
var x = new Mixed2("hello");
x.a;
x.p;
Mixed2.p;
}
function f4() {
var x = new Mixed3("hello");
x.a;
x.p;
x.f();
Mixed3.p;
Mixed3.f();
}
function f5() {
var x = new Mixed4("hello");
x.a;
x.p;
x.f();
Mixed4.p;
Mixed4.f();
}
function f6() {
var x = new Mixed5();
x.p;
x.f();
Mixed5.p;
Mixed5.f();
}
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
var _this = _super.call(this, "hello") || this;
_this.a;
_this.b;
_this.p;
return _this;
}
return C2;
}(Mixed1));
var C3 = (function (_super) {
__extends(C3, _super);
function C3() {
var _this = _super.call(this, 42) || this;
_this.a;
_this.b;
_this.p;
_this.f();
return _this;
}
C3.prototype.f = function () { return _super.prototype.f.call(this); };
return C3;
}(Mixed3));
//// [mixinClassesMembers.d.ts]
declare class C1 {
a: number;
protected b: number;
private c;
constructor(s: string);
constructor(n: number);
}
declare class M1 {
constructor(...args: any[]);
p: number;
static p: number;
}
declare class M2 {
constructor(...args: any[]);
f(): number;
static f(): number;
}
declare const Mixed1: typeof M1 & typeof C1;
declare const Mixed2: typeof C1 & typeof M1;
declare const Mixed3: typeof M2 & typeof M1 & typeof C1;
declare const Mixed4: typeof C1 & typeof M1 & typeof M2;
declare const Mixed5: typeof M1 & typeof M2;
declare function f1(): void;
declare function f2(): void;
declare function f3(): void;
declare function f4(): void;
declare function f5(): void;
declare function f6(): void;
declare class C2 extends Mixed1 {
constructor();
}
declare class C3 extends Mixed3 {
constructor();
f(): number;
}

View file

@ -0,0 +1,309 @@
=== tests/cases/conformance/classes/mixinClassesMembers.ts ===
declare class C1 {
>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0))
public a: number;
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
protected b: number;
>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21))
private c: number;
>c : Symbol(C1.c, Decl(mixinClassesMembers.ts, 3, 24))
constructor(s: string);
>s : Symbol(s, Decl(mixinClassesMembers.ts, 5, 16))
constructor(n: number);
>n : Symbol(n, Decl(mixinClassesMembers.ts, 6, 16))
}
declare class M1 {
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
constructor(...args: any[]);
>args : Symbol(args, Decl(mixinClassesMembers.ts, 10, 16))
p: number;
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
static p: number;
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
}
declare class M2 {
>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1))
constructor(...args: any[]);
>args : Symbol(args, Decl(mixinClassesMembers.ts, 16, 16))
f(): number;
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
static f(): number;
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
}
declare const Mixed1: typeof M1 & typeof C1;
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0))
declare const Mixed2: typeof C1 & typeof M1;
>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13))
>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0))
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
declare const Mixed3: typeof M2 & typeof M1 & typeof C1;
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1))
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0))
declare const Mixed4: typeof C1 & typeof M1 & typeof M2;
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0))
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1))
declare const Mixed5: typeof M1 & typeof M2;
>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13))
>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1))
>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1))
function f1() {
>f1 : Symbol(f1, Decl(mixinClassesMembers.ts, 25, 44))
let x1 = new Mixed1("hello");
>x1 : Symbol(x1, Decl(mixinClassesMembers.ts, 28, 7))
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
let x2 = new Mixed1(42);
>x2 : Symbol(x2, Decl(mixinClassesMembers.ts, 29, 7))
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
let x3 = new Mixed2("hello");
>x3 : Symbol(x3, Decl(mixinClassesMembers.ts, 30, 7))
>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13))
let x4 = new Mixed2(42);
>x4 : Symbol(x4, Decl(mixinClassesMembers.ts, 31, 7))
>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13))
let x5 = new Mixed3("hello");
>x5 : Symbol(x5, Decl(mixinClassesMembers.ts, 32, 7))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
let x6 = new Mixed3(42);
>x6 : Symbol(x6, Decl(mixinClassesMembers.ts, 33, 7))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
let x7 = new Mixed4("hello");
>x7 : Symbol(x7, Decl(mixinClassesMembers.ts, 34, 7))
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
let x8 = new Mixed4(42);
>x8 : Symbol(x8, Decl(mixinClassesMembers.ts, 35, 7))
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
let x9 = new Mixed5();
>x9 : Symbol(x9, Decl(mixinClassesMembers.ts, 36, 7))
>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13))
}
function f2() {
>f2 : Symbol(f2, Decl(mixinClassesMembers.ts, 37, 1))
let x = new Mixed1("hello");
>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7))
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
x.a;
>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
x.p;
>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
Mixed1.p;
>Mixed1.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
}
function f3() {
>f3 : Symbol(f3, Decl(mixinClassesMembers.ts, 44, 1))
let x = new Mixed2("hello");
>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7))
>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13))
x.a;
>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
x.p;
>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
Mixed2.p;
>Mixed2.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
}
function f4() {
>f4 : Symbol(f4, Decl(mixinClassesMembers.ts, 51, 1))
let x = new Mixed3("hello");
>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
x.a;
>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
x.p;
>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
x.f();
>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
Mixed3.p;
>Mixed3.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
Mixed3.f();
>Mixed3.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
}
function f5() {
>f5 : Symbol(f5, Decl(mixinClassesMembers.ts, 60, 1))
let x = new Mixed4("hello");
>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7))
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
x.a;
>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
x.p;
>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
x.f();
>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
Mixed4.p;
>Mixed4.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
Mixed4.f();
>Mixed4.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
}
function f6() {
>f6 : Symbol(f6, Decl(mixinClassesMembers.ts, 69, 1))
let x = new Mixed5();
>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7))
>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13))
x.p;
>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
x.f();
>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
Mixed5.p;
>Mixed5.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14))
Mixed5.f();
>Mixed5.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16))
}
class C2 extends Mixed1 {
>C2 : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1))
>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13))
constructor() {
super("hello");
this.a;
>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
this.b;
>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21))
>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1))
>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21))
this.p;
>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
}
}
class C3 extends Mixed3 {
>C3 : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1))
>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13))
constructor() {
super(42);
this.a;
>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1))
>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18))
this.b;
>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21))
>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1))
>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21))
this.p;
>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1))
>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32))
this.f();
>this.f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5))
>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1))
>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5))
}
f() { return super.f(); }
>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5))
>super.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32))
}

View file

@ -0,0 +1,352 @@
=== tests/cases/conformance/classes/mixinClassesMembers.ts ===
declare class C1 {
>C1 : C1
public a: number;
>a : number
protected b: number;
>b : number
private c: number;
>c : number
constructor(s: string);
>s : string
constructor(n: number);
>n : number
}
declare class M1 {
>M1 : M1
constructor(...args: any[]);
>args : any[]
p: number;
>p : number
static p: number;
>p : number
}
declare class M2 {
>M2 : M2
constructor(...args: any[]);
>args : any[]
f(): number;
>f : () => number
static f(): number;
>f : () => number
}
declare const Mixed1: typeof M1 & typeof C1;
>Mixed1 : typeof M1 & typeof C1
>M1 : typeof M1
>C1 : typeof C1
declare const Mixed2: typeof C1 & typeof M1;
>Mixed2 : typeof C1 & typeof M1
>C1 : typeof C1
>M1 : typeof M1
declare const Mixed3: typeof M2 & typeof M1 & typeof C1;
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>M2 : typeof M2
>M1 : typeof M1
>C1 : typeof C1
declare const Mixed4: typeof C1 & typeof M1 & typeof M2;
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>C1 : typeof C1
>M1 : typeof M1
>M2 : typeof M2
declare const Mixed5: typeof M1 & typeof M2;
>Mixed5 : typeof M1 & typeof M2
>M1 : typeof M1
>M2 : typeof M2
function f1() {
>f1 : () => void
let x1 = new Mixed1("hello");
>x1 : M1 & C1
>new Mixed1("hello") : M1 & C1
>Mixed1 : typeof M1 & typeof C1
>"hello" : "hello"
let x2 = new Mixed1(42);
>x2 : M1 & C1
>new Mixed1(42) : M1 & C1
>Mixed1 : typeof M1 & typeof C1
>42 : 42
let x3 = new Mixed2("hello");
>x3 : C1 & M1
>new Mixed2("hello") : C1 & M1
>Mixed2 : typeof C1 & typeof M1
>"hello" : "hello"
let x4 = new Mixed2(42);
>x4 : C1 & M1
>new Mixed2(42) : C1 & M1
>Mixed2 : typeof C1 & typeof M1
>42 : 42
let x5 = new Mixed3("hello");
>x5 : M2 & M1 & C1
>new Mixed3("hello") : M2 & M1 & C1
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>"hello" : "hello"
let x6 = new Mixed3(42);
>x6 : M2 & M1 & C1
>new Mixed3(42) : M2 & M1 & C1
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>42 : 42
let x7 = new Mixed4("hello");
>x7 : C1 & M1 & M2
>new Mixed4("hello") : C1 & M1 & M2
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>"hello" : "hello"
let x8 = new Mixed4(42);
>x8 : C1 & M1 & M2
>new Mixed4(42) : C1 & M1 & M2
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>42 : 42
let x9 = new Mixed5();
>x9 : M1 & M2
>new Mixed5() : M1 & M2
>Mixed5 : typeof M1 & typeof M2
}
function f2() {
>f2 : () => void
let x = new Mixed1("hello");
>x : M1 & C1
>new Mixed1("hello") : M1 & C1
>Mixed1 : typeof M1 & typeof C1
>"hello" : "hello"
x.a;
>x.a : number
>x : M1 & C1
>a : number
x.p;
>x.p : number
>x : M1 & C1
>p : number
Mixed1.p;
>Mixed1.p : number
>Mixed1 : typeof M1 & typeof C1
>p : number
}
function f3() {
>f3 : () => void
let x = new Mixed2("hello");
>x : C1 & M1
>new Mixed2("hello") : C1 & M1
>Mixed2 : typeof C1 & typeof M1
>"hello" : "hello"
x.a;
>x.a : number
>x : C1 & M1
>a : number
x.p;
>x.p : number
>x : C1 & M1
>p : number
Mixed2.p;
>Mixed2.p : number
>Mixed2 : typeof C1 & typeof M1
>p : number
}
function f4() {
>f4 : () => void
let x = new Mixed3("hello");
>x : M2 & M1 & C1
>new Mixed3("hello") : M2 & M1 & C1
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>"hello" : "hello"
x.a;
>x.a : number
>x : M2 & M1 & C1
>a : number
x.p;
>x.p : number
>x : M2 & M1 & C1
>p : number
x.f();
>x.f() : number
>x.f : () => number
>x : M2 & M1 & C1
>f : () => number
Mixed3.p;
>Mixed3.p : number
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>p : number
Mixed3.f();
>Mixed3.f() : number
>Mixed3.f : () => number
>Mixed3 : typeof M2 & typeof M1 & typeof C1
>f : () => number
}
function f5() {
>f5 : () => void
let x = new Mixed4("hello");
>x : C1 & M1 & M2
>new Mixed4("hello") : C1 & M1 & M2
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>"hello" : "hello"
x.a;
>x.a : number
>x : C1 & M1 & M2
>a : number
x.p;
>x.p : number
>x : C1 & M1 & M2
>p : number
x.f();
>x.f() : number
>x.f : () => number
>x : C1 & M1 & M2
>f : () => number
Mixed4.p;
>Mixed4.p : number
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>p : number
Mixed4.f();
>Mixed4.f() : number
>Mixed4.f : () => number
>Mixed4 : typeof C1 & typeof M1 & typeof M2
>f : () => number
}
function f6() {
>f6 : () => void
let x = new Mixed5();
>x : M1 & M2
>new Mixed5() : M1 & M2
>Mixed5 : typeof M1 & typeof M2
x.p;
>x.p : number
>x : M1 & M2
>p : number
x.f();
>x.f() : number
>x.f : () => number
>x : M1 & M2
>f : () => number
Mixed5.p;
>Mixed5.p : number
>Mixed5 : typeof M1 & typeof M2
>p : number
Mixed5.f();
>Mixed5.f() : number
>Mixed5.f : () => number
>Mixed5 : typeof M1 & typeof M2
>f : () => number
}
class C2 extends Mixed1 {
>C2 : C2
>Mixed1 : M1 & C1
constructor() {
super("hello");
>super("hello") : void
>super : typeof M1 & typeof C1
>"hello" : "hello"
this.a;
>this.a : number
>this : this
>a : number
this.b;
>this.b : number
>this : this
>b : number
this.p;
>this.p : number
>this : this
>p : number
}
}
class C3 extends Mixed3 {
>C3 : C3
>Mixed3 : M2 & M1 & C1
constructor() {
super(42);
>super(42) : void
>super : typeof M2 & typeof M1 & typeof C1
>42 : 42
this.a;
>this.a : number
>this : this
>a : number
this.b;
>this.b : number
>this : this
>b : number
this.p;
>this.p : number
>this : this
>p : number
this.f();
>this.f() : number
>this.f : () => number
>this : this
>f : () => number
}
f() { return super.f(); }
>f : () => number
>super.f() : number
>super.f : () => number
>super : M2 & M1 & C1
>f : () => number
}

View file

@ -0,0 +1,67 @@
// @declaration: true
type Constructor<T> = new(...args: any[]) => T;
class Base {
constructor(public x: number, public y: number) {}
}
class Derived extends Base {
constructor(x: number, y: number, public z: number) {
super(x, y);
}
}
interface Printable {
print(): void;
}
const Printable = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
interface Tagged {
_tag: string;
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
class C extends superClass {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "hello";
}
}
return C;
}
const Thing1 = Tagged(Derived);
const Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
const thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
const thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
class Thing3 extends Thing2 {
constructor(tag: string) {
super(10, 20, 30);
this._tag = tag;
}
test() {
this.print();
}
}

View file

@ -0,0 +1,56 @@
type Constructor<T> = new(...args: any[]) => T;
class Base {
constructor(public x: number, public y: number) {}
}
class Derived extends Base {
constructor(x: number, y: number, public z: number) {
super(x, y);
}
}
const Printable = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
function Tagged<T extends Constructor<{}>>(superClass: T) {
class C extends superClass {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "hello";
}
}
return C;
}
const Thing1 = Tagged(Derived);
const Thing2 = Tagged(Printable(Derived));
Thing2.message;
function f1() {
const thing = new Thing1(1, 2, 3);
thing.x;
thing._tag;
}
function f2() {
const thing = new Thing2(1, 2, 3);
thing.x;
thing._tag;
thing.print();
}
class Thing3 extends Thing2 {
constructor(tag: string) {
super(10, 20, 30);
this._tag = tag;
}
test() {
this.print();
}
}

View file

@ -0,0 +1,99 @@
// @declaration: true
declare class C1 {
public a: number;
protected b: number;
private c: number;
constructor(s: string);
constructor(n: number);
}
declare class M1 {
constructor(...args: any[]);
p: number;
static p: number;
}
declare class M2 {
constructor(...args: any[]);
f(): number;
static f(): number;
}
declare const Mixed1: typeof M1 & typeof C1;
declare const Mixed2: typeof C1 & typeof M1;
declare const Mixed3: typeof M2 & typeof M1 & typeof C1;
declare const Mixed4: typeof C1 & typeof M1 & typeof M2;
declare const Mixed5: typeof M1 & typeof M2;
function f1() {
let x1 = new Mixed1("hello");
let x2 = new Mixed1(42);
let x3 = new Mixed2("hello");
let x4 = new Mixed2(42);
let x5 = new Mixed3("hello");
let x6 = new Mixed3(42);
let x7 = new Mixed4("hello");
let x8 = new Mixed4(42);
let x9 = new Mixed5();
}
function f2() {
let x = new Mixed1("hello");
x.a;
x.p;
Mixed1.p;
}
function f3() {
let x = new Mixed2("hello");
x.a;
x.p;
Mixed2.p;
}
function f4() {
let x = new Mixed3("hello");
x.a;
x.p;
x.f();
Mixed3.p;
Mixed3.f();
}
function f5() {
let x = new Mixed4("hello");
x.a;
x.p;
x.f();
Mixed4.p;
Mixed4.f();
}
function f6() {
let x = new Mixed5();
x.p;
x.f();
Mixed5.p;
Mixed5.f();
}
class C2 extends Mixed1 {
constructor() {
super("hello");
this.a;
this.b;
this.p;
}
}
class C3 extends Mixed3 {
constructor() {
super(42);
this.a;
this.b;
this.p;
this.f();
}
f() { return super.f(); }
}