Skip to content

Commit

Permalink
Merge pull request #13820 from Microsoft/fixBaseClassCheck
Browse files Browse the repository at this point in the history
Fix base class check to allow 'object' type
  • Loading branch information
ahejlsberg authored Feb 1, 2017
2 parents 207f1aa + 3a0a58d commit 1530a60
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3991,7 +3991,7 @@ namespace ts {
// A valid base type is any non-generic object type or intersection of non-generic
// object types.
function isValidBaseType(type: Type): boolean {
return type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive) && !isGenericMappedType(type) ||
type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
}

Expand Down Expand Up @@ -4944,7 +4944,7 @@ namespace ts {
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() :
t.flags & TypeFlags.NonPrimitive ? globalObjectType :
t.flags & TypeFlags.NonPrimitive ? emptyObjectType :
t;
}

Expand Down
20 changes: 20 additions & 0 deletions tests/baselines/reference/mixinClassesAnonymous.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ class Thing3 extends Thing2 {
this.print();
}
}

// Repro from #13805

const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
return class extends Base {
timestamp = new Date();
};
}


//// [mixinClassesAnonymous.js]
Expand Down Expand Up @@ -138,3 +146,15 @@ var Thing3 = (function (_super) {
};
return Thing3;
}(Thing2));
// Repro from #13805
var Timestamped = function (Base) {
return (function (_super) {
__extends(class_2, _super);
function class_2() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.timestamp = new Date();
return _this;
}
return class_2;
}(Base));
};
19 changes: 19 additions & 0 deletions tests/baselines/reference/mixinClassesAnonymous.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,22 @@ class Thing3 extends Thing2 {
}
}

// Repro from #13805

const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
>Timestamped : Symbol(Timestamped, Decl(mixinClassesAnonymous.ts, 59, 5))
>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0))
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53))
>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21))

return class extends Base {
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53))

timestamp = new Date();
>timestamp : Symbol((Anonymous class).timestamp, Decl(mixinClassesAnonymous.ts, 60, 31))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))

};
}

22 changes: 22 additions & 0 deletions tests/baselines/reference/mixinClassesAnonymous.types
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,25 @@ class Thing3 extends Thing2 {
}
}

// Repro from #13805

const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
>Timestamped : <CT extends Constructor<object>>(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
><CT extends Constructor<object>>(Base: CT) => { return class extends Base { timestamp = new Date(); };} : <CT extends Constructor<object>>(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
>CT : CT
>Constructor : Constructor<T>
>Base : CT
>CT : CT

return class extends Base {
>class extends Base { timestamp = new Date(); } : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
>Base : object

timestamp = new Date();
>timestamp : Date
>new Date() : Date
>Date : DateConstructor

};
}

4 changes: 2 additions & 2 deletions tests/baselines/reference/nonPrimitiveAssignError.errors.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(5,1): error TS2322: Type 'object' is not assignable to type '{ foo: string; }'.
Property 'foo' is missing in type 'Object'.
Property 'foo' is missing in type '{}'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(13,1): error TS2322: Type 'number' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(14,1): error TS2322: Type 'true' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(15,1): error TS2322: Type 'string' is not assignable to type 'object'.
Expand All @@ -16,7 +16,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(19,1): err
y = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type '{ foo: string; }'.
!!! error TS2322: Property 'foo' is missing in type 'Object'.
!!! error TS2322: Property 'foo' is missing in type '{}'.
a = x;
a = y;

Expand Down
8 changes: 8 additions & 0 deletions tests/cases/conformance/classes/mixinClassesAnonymous.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,11 @@ class Thing3 extends Thing2 {
this.print();
}
}

// Repro from #13805

const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
return class extends Base {
timestamp = new Date();
};
}

0 comments on commit 1530a60

Please sign in to comment.