Merge pull request #13427 from Microsoft/nonPrimitiveObjectRelations
Unconstrained type parameter not assignable to 'object' type
This commit is contained in:
commit
0f49703030
4 changed files with 70 additions and 37 deletions
|
@ -7172,8 +7172,7 @@ namespace ts {
|
|||
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && isEnumTypeRelatedTo(<EnumType>source, <EnumType>target, errorReporter)) return true;
|
||||
if (source.flags & TypeFlags.Undefined && (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void))) return true;
|
||||
if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true;
|
||||
if (source.flags & TypeFlags.Object && target === nonPrimitiveType) return true;
|
||||
if (source.flags & TypeFlags.Primitive && target === nonPrimitiveType) return false;
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.NonPrimitive) return true;
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (source.flags & TypeFlags.Any) return true;
|
||||
if ((source.flags & TypeFlags.Number | source.flags & TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true;
|
||||
|
@ -7457,19 +7456,19 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
|
||||
// The constraint may need to be further instantiated with its 'this' type.
|
||||
constraint = getTypeWithThisArgument(constraint, source);
|
||||
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
// A type parameter with no constraint is not related to the non-primitive object type.
|
||||
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// The constraint may need to be further instantiated with its 'this' type.
|
||||
constraint = getTypeWithThisArgument(constraint, source);
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9237,9 +9236,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getTypeFacts(type: Type): TypeFacts {
|
||||
if (type === nonPrimitiveType) {
|
||||
return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
|
||||
}
|
||||
const flags = type.flags;
|
||||
if (flags & TypeFlags.String) {
|
||||
return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts;
|
||||
|
@ -9280,6 +9276,9 @@ namespace ts {
|
|||
if (flags & TypeFlags.ESSymbol) {
|
||||
return strictNullChecks ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts;
|
||||
}
|
||||
if (flags & TypeFlags.NonPrimitive) {
|
||||
return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
|
||||
}
|
||||
if (flags & TypeFlags.TypeParameter) {
|
||||
const constraint = getConstraintOfTypeParameter(<TypeParameter>type);
|
||||
return getTypeFacts(constraint || emptyObjectType);
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(7,17): error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(8,17): error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(14,7): error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(15,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(21,8): error TS2344: Type 'number' does not satisfy the constraint 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(22,8): error TS2344: Type 'string' does not satisfy the constraint 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(26,14): error TS2344: Type 'number' does not satisfy the constraint 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(2,9): error TS2322: Type 'T' is not assignable to type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(9,17): error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(10,17): error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(18,7): error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(19,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(25,8): error TS2344: Type 'number' does not satisfy the constraint 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(26,8): error TS2344: Type 'string' does not satisfy the constraint 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(34,14): error TS2344: Type 'number' does not satisfy the constraint 'object'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts (7 errors) ====
|
||||
function generic<T>(t: T) {}
|
||||
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts (8 errors) ====
|
||||
function generic<T>(t: T) {
|
||||
var o: object = t; // expect error
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'object'.
|
||||
}
|
||||
var a = {};
|
||||
var b = "42";
|
||||
|
||||
|
@ -21,7 +26,9 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(26,14): erro
|
|||
~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
|
||||
|
||||
function bound<T extends object>(t: T) {}
|
||||
function bound<T extends object>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
bound({});
|
||||
bound(a);
|
||||
|
@ -43,6 +50,10 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(26,14): erro
|
|||
~~~~~~
|
||||
!!! error TS2344: Type 'string' does not satisfy the constraint 'object'.
|
||||
|
||||
function bound3<T extends {}>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
interface Proxy<T extends object> {}
|
||||
|
||||
var x: Proxy<number>; // error
|
||||
|
@ -53,7 +64,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts(26,14): erro
|
|||
|
||||
|
||||
interface Blah {
|
||||
foo: number;
|
||||
foo: number;
|
||||
}
|
||||
|
||||
var u: Proxy<Blah>; // ok
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//// [nonPrimitiveInGeneric.ts]
|
||||
function generic<T>(t: T) {}
|
||||
function generic<T>(t: T) {
|
||||
var o: object = t; // expect error
|
||||
}
|
||||
var a = {};
|
||||
var b = "42";
|
||||
|
||||
|
@ -8,7 +10,9 @@ generic<object>(a);
|
|||
generic<object>(123); // expect error
|
||||
generic<object>(b); // expect error
|
||||
|
||||
function bound<T extends object>(t: T) {}
|
||||
function bound<T extends object>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
bound({});
|
||||
bound(a);
|
||||
|
@ -22,6 +26,10 @@ bound2<Object>();
|
|||
bound2<number>(); // expect error
|
||||
bound2<string>(); // expect error
|
||||
|
||||
function bound3<T extends {}>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
interface Proxy<T extends object> {}
|
||||
|
||||
var x: Proxy<number>; // error
|
||||
|
@ -30,21 +38,25 @@ var z: Proxy<undefined> ; // ok
|
|||
|
||||
|
||||
interface Blah {
|
||||
foo: number;
|
||||
foo: number;
|
||||
}
|
||||
|
||||
var u: Proxy<Blah>; // ok
|
||||
|
||||
|
||||
//// [nonPrimitiveInGeneric.js]
|
||||
function generic(t) { }
|
||||
function generic(t) {
|
||||
var o = t; // expect error
|
||||
}
|
||||
var a = {};
|
||||
var b = "42";
|
||||
generic({});
|
||||
generic(a);
|
||||
generic(123); // expect error
|
||||
generic(b); // expect error
|
||||
function bound(t) { }
|
||||
function bound(t) {
|
||||
var o = t; // ok
|
||||
}
|
||||
bound({});
|
||||
bound(a);
|
||||
bound(123); // expect error
|
||||
|
@ -54,6 +66,9 @@ bound2();
|
|||
bound2();
|
||||
bound2(); // expect error
|
||||
bound2(); // expect error
|
||||
function bound3(t) {
|
||||
var o = t; // ok
|
||||
}
|
||||
var x; // error
|
||||
var y; // ok
|
||||
var z; // ok
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
function generic<T>(t: T) {}
|
||||
function generic<T>(t: T) {
|
||||
var o: object = t; // expect error
|
||||
}
|
||||
var a = {};
|
||||
var b = "42";
|
||||
|
||||
|
@ -7,7 +9,9 @@ generic<object>(a);
|
|||
generic<object>(123); // expect error
|
||||
generic<object>(b); // expect error
|
||||
|
||||
function bound<T extends object>(t: T) {}
|
||||
function bound<T extends object>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
bound({});
|
||||
bound(a);
|
||||
|
@ -21,6 +25,10 @@ bound2<Object>();
|
|||
bound2<number>(); // expect error
|
||||
bound2<string>(); // expect error
|
||||
|
||||
function bound3<T extends {}>(t: T) {
|
||||
var o: object = t; // ok
|
||||
}
|
||||
|
||||
interface Proxy<T extends object> {}
|
||||
|
||||
var x: Proxy<number>; // error
|
||||
|
@ -29,7 +37,7 @@ var z: Proxy<undefined> ; // ok
|
|||
|
||||
|
||||
interface Blah {
|
||||
foo: number;
|
||||
foo: number;
|
||||
}
|
||||
|
||||
var u: Proxy<Blah>; // ok
|
||||
|
|
Loading…
Reference in a new issue