Merge pull request #12501 from HerringtonDarkholme/non-primitive

Fix #1809, introduce non primitive object type
This commit is contained in:
Nathan Shively-Sanders 2017-01-06 09:51:08 -08:00 committed by GitHub
commit e9e7fcecbd
36 changed files with 978 additions and 7 deletions

View file

@ -3146,6 +3146,7 @@ namespace ts {
case SyntaxKind.AnyKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
@ -3344,6 +3345,7 @@ namespace ts {
case SyntaxKind.NumberKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:

View file

@ -148,6 +148,7 @@ namespace ts {
const voidType = createIntrinsicType(TypeFlags.Void, "void");
const neverType = createIntrinsicType(TypeFlags.Never, "never");
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@ -4196,6 +4197,7 @@ namespace ts {
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
@ -4780,6 +4782,7 @@ namespace ts {
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() :
t.flags & TypeFlags.NonPrimitive ? globalObjectType :
t;
}
@ -6405,6 +6408,8 @@ namespace ts {
return nullType;
case SyntaxKind.NeverKeyword:
return neverType;
case SyntaxKind.ObjectKeyword:
return nonPrimitiveType;
case SyntaxKind.JSDocNullKeyword:
return nullType;
case SyntaxKind.JSDocUndefinedKeyword:
@ -7162,6 +7167,8 @@ 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 (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;
@ -9235,6 +9242,9 @@ 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;
@ -18159,6 +18169,7 @@ namespace ts {
case "string":
case "symbol":
case "void":
case "object":
error(name, message, (<Identifier>name).text);
}
}

View file

@ -2510,6 +2510,7 @@ namespace ts {
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ObjectKeyword:
// If these are followed by a dot, then parse these out as a dotted type reference instead.
const node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReference();
@ -2568,6 +2569,7 @@ namespace ts {
case SyntaxKind.NumericLiteral:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.ObjectKeyword:
return true;
case SyntaxKind.MinusToken:
return lookAhead(nextTokenIsNumericLiteral);
@ -6037,6 +6039,7 @@ namespace ts {
case SyntaxKind.NullKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ObjectKeyword:
return parseTokenNode<JSDocType>();
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:

View file

@ -98,6 +98,7 @@ namespace ts {
"new": SyntaxKind.NewKeyword,
"null": SyntaxKind.NullKeyword,
"number": SyntaxKind.NumberKeyword,
"object": SyntaxKind.ObjectKeyword,
"package": SyntaxKind.PackageKeyword,
"private": SyntaxKind.PrivateKeyword,
"protected": SyntaxKind.ProtectedKeyword,

View file

@ -175,6 +175,7 @@ namespace ts {
ReadonlyKeyword,
RequireKeyword,
NumberKeyword,
ObjectKeyword,
SetKeyword,
StringKeyword,
SymbolKeyword,
@ -816,6 +817,7 @@ namespace ts {
export interface KeywordTypeNode extends TypeNode {
kind: SyntaxKind.AnyKeyword
| SyntaxKind.NumberKeyword
| SyntaxKind.ObjectKeyword
| SyntaxKind.BooleanKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SymbolKeyword
@ -2785,6 +2787,7 @@ namespace ts {
ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
NonPrimitive = 1 << 24, // intrinsic object type
/* @internal */
Nullable = Undefined | Null,
@ -2794,7 +2797,7 @@ namespace ts {
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
PossiblyFalsy = DefinitelyFalsy | String | Number | Boolean,
/* @internal */
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never,
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
/* @internal */
Primitive = String | Number | Boolean | Enum | ESSymbol | Void | Undefined | Null | Literal,
StringLike = String | StringLiteral | Index,
@ -2808,8 +2811,8 @@ namespace ts {
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol,
NotUnionOrUnit = Any | ESSymbol | Object,
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol | NonPrimitive,
NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
@ -2863,6 +2866,7 @@ namespace ts {
ObjectLiteral = 1 << 7, // Originates in an object literal
EvolvingArray = 1 << 8, // Evolving array type
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
NonPrimitive = 1 << 10, // NonPrimitive object type
ClassOrInterface = Class | Interface
}

View file

@ -0,0 +1,14 @@
//// [assignObjectToNonPrimitive.ts]
var x = {};
var y = {foo: "bar"};
var a: object;
a = x;
a = y;
//// [assignObjectToNonPrimitive.js]
var x = {};
var y = { foo: "bar" };
var a;
a = x;
a = y;

View file

@ -0,0 +1,19 @@
=== tests/cases/conformance/types/nonPrimitive/assignObjectToNonPrimitive.ts ===
var x = {};
>x : Symbol(x, Decl(assignObjectToNonPrimitive.ts, 0, 3))
var y = {foo: "bar"};
>y : Symbol(y, Decl(assignObjectToNonPrimitive.ts, 1, 3))
>foo : Symbol(foo, Decl(assignObjectToNonPrimitive.ts, 1, 9))
var a: object;
>a : Symbol(a, Decl(assignObjectToNonPrimitive.ts, 2, 3))
a = x;
>a : Symbol(a, Decl(assignObjectToNonPrimitive.ts, 2, 3))
>x : Symbol(x, Decl(assignObjectToNonPrimitive.ts, 0, 3))
a = y;
>a : Symbol(a, Decl(assignObjectToNonPrimitive.ts, 2, 3))
>y : Symbol(y, Decl(assignObjectToNonPrimitive.ts, 1, 3))

View file

@ -0,0 +1,24 @@
=== tests/cases/conformance/types/nonPrimitive/assignObjectToNonPrimitive.ts ===
var x = {};
>x : {}
>{} : {}
var y = {foo: "bar"};
>y : { foo: string; }
>{foo: "bar"} : { foo: string; }
>foo : string
>"bar" : "bar"
var a: object;
>a : object
a = x;
>a = x : {}
>a : object
>x : {}
a = y;
>a = y : { foo: string; }
>a : object
>y : { foo: string; }

View file

@ -0,0 +1,10 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(3,3): error TS2339: Property 'nonExist' does not exist on type 'object'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (1 errors) ====
var a: object;
a.toString();
a.nonExist(); // error
~~~~~~~~
!!! error TS2339: Property 'nonExist' does not exist on type 'object'.

View file

@ -0,0 +1,10 @@
//// [nonPrimitiveAccessProperty.ts]
var a: object;
a.toString();
a.nonExist(); // error
//// [nonPrimitiveAccessProperty.js]
var a;
a.toString();
a.nonExist(); // error

View file

@ -0,0 +1,18 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts(7,5): error TS2322: Type '{ foo: string; }' is not assignable to type 'WithNonPrimitive'.
Types of property 'foo' are incompatible.
Type 'string' is not assignable to type 'object'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts (1 errors) ====
interface WithNonPrimitive {
foo: object
}
var a: WithNonPrimitive = { foo: {bar: "bar"} };
var b: WithNonPrimitive = {foo: "bar"}; // expect error
~
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'WithNonPrimitive'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'object'.

View file

@ -0,0 +1,13 @@
//// [nonPrimitiveAsProperty.ts]
interface WithNonPrimitive {
foo: object
}
var a: WithNonPrimitive = { foo: {bar: "bar"} };
var b: WithNonPrimitive = {foo: "bar"}; // expect error
//// [nonPrimitiveAsProperty.js]
var a = { foo: { bar: "bar" } };
var b = { foo: "bar" }; // expect error

View file

@ -0,0 +1,54 @@
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'.
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'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(17,1): error TS2322: Type 'object' is not assignable to type 'number'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(18,1): error TS2322: Type 'object' is not assignable to type 'boolean'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(19,1): error TS2322: Type 'object' is not assignable to type 'string'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts (7 errors) ====
var x = {};
var y = {foo: "bar"};
var a: object;
x = a;
y = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type '{ foo: string; }'.
!!! error TS2322: Property 'foo' is missing in type 'Object'.
a = x;
a = y;
var n = 123;
var b = true;
var s = "fooo";
a = n; // expect error
~
!!! error TS2322: Type 'number' is not assignable to type 'object'.
a = b; // expect error
~
!!! error TS2322: Type 'true' is not assignable to type 'object'.
a = s; // expect error
~
!!! error TS2322: Type 'string' is not assignable to type 'object'.
n = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type 'number'.
b = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type 'boolean'.
s = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type 'string'.
var numObj: Number = 123;
var boolObj: Boolean = true;
var strObj: String = "string";
a = numObj; // ok
a = boolObj; // ok
a = strObj; // ok

View file

@ -0,0 +1,53 @@
//// [nonPrimitiveAssignError.ts]
var x = {};
var y = {foo: "bar"};
var a: object;
x = a;
y = a; // expect error
a = x;
a = y;
var n = 123;
var b = true;
var s = "fooo";
a = n; // expect error
a = b; // expect error
a = s; // expect error
n = a; // expect error
b = a; // expect error
s = a; // expect error
var numObj: Number = 123;
var boolObj: Boolean = true;
var strObj: String = "string";
a = numObj; // ok
a = boolObj; // ok
a = strObj; // ok
//// [nonPrimitiveAssignError.js]
var x = {};
var y = { foo: "bar" };
var a;
x = a;
y = a; // expect error
a = x;
a = y;
var n = 123;
var b = true;
var s = "fooo";
a = n; // expect error
a = b; // expect error
a = s; // expect error
n = a; // expect error
b = a; // expect error
s = a; // expect error
var numObj = 123;
var boolObj = true;
var strObj = "string";
a = numObj; // ok
a = boolObj; // ok
a = strObj; // ok

View file

@ -0,0 +1,31 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts(12,12): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts(13,1): error TS2322: Type 'object' is not assignable to type 'boolean'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts(17,12): error TS2322: Type 'number' is not assignable to type 'object'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts (3 errors) ====
function takeObject(o: object) {}
function returnObject(): object {
return {};
}
var nonPrimitive: object;
var primitive: boolean;
takeObject(nonPrimitive);
nonPrimitive = returnObject();
takeObject(primitive); // expect error
~~~~~~~~~
!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'object'.
primitive = returnObject(); // expect error
~~~~~~~~~
!!! error TS2322: Type 'object' is not assignable to type 'boolean'.
function returnError(): object {
var ret = 123;
return ret; // expect error
~~~
!!! error TS2322: Type 'number' is not assignable to type 'object'.
}

View file

@ -0,0 +1,36 @@
//// [nonPrimitiveInFunction.ts]
function takeObject(o: object) {}
function returnObject(): object {
return {};
}
var nonPrimitive: object;
var primitive: boolean;
takeObject(nonPrimitive);
nonPrimitive = returnObject();
takeObject(primitive); // expect error
primitive = returnObject(); // expect error
function returnError(): object {
var ret = 123;
return ret; // expect error
}
//// [nonPrimitiveInFunction.js]
function takeObject(o) { }
function returnObject() {
return {};
}
var nonPrimitive;
var primitive;
takeObject(nonPrimitive);
nonPrimitive = returnObject();
takeObject(primitive); // expect error
primitive = returnObject(); // expect error
function returnError() {
var ret = 123;
return ret; // expect error
}

View file

@ -0,0 +1,60 @@
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 (7 errors) ====
function generic<T>(t: T) {}
var a = {};
var b = "42";
generic<object>({});
generic<object>(a);
generic<object>(123); // expect error
~~~
!!! error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
generic<object>(b); // expect error
~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
function bound<T extends object>(t: T) {}
bound({});
bound(a);
bound(123); // expect error
~~~
!!! error TS2345: Argument of type '123' is not assignable to parameter of type 'object'.
bound(b); // expect error
~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'object'.
function bound2<T extends object>() {}
bound2<{}>();
bound2<Object>();
bound2<number>(); // expect error
~~~~~~
!!! error TS2344: Type 'number' does not satisfy the constraint 'object'.
bound2<string>(); // expect error
~~~~~~
!!! error TS2344: Type 'string' does not satisfy the constraint 'object'.
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
~~~~~~
!!! error TS2344: Type 'number' does not satisfy the constraint 'object'.
var y: Proxy<null>; // ok
var z: Proxy<undefined> ; // ok
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok

View file

@ -0,0 +1,60 @@
//// [nonPrimitiveInGeneric.ts]
function generic<T>(t: T) {}
var a = {};
var b = "42";
generic<object>({});
generic<object>(a);
generic<object>(123); // expect error
generic<object>(b); // expect error
function bound<T extends object>(t: T) {}
bound({});
bound(a);
bound(123); // expect error
bound(b); // expect error
function bound2<T extends object>() {}
bound2<{}>();
bound2<Object>();
bound2<number>(); // expect error
bound2<string>(); // expect error
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
var y: Proxy<null>; // ok
var z: Proxy<undefined> ; // ok
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok
//// [nonPrimitiveInGeneric.js]
function generic(t) { }
var a = {};
var b = "42";
generic({});
generic(a);
generic(123); // expect error
generic(b); // expect error
function bound(t) { }
bound({});
bound(a);
bound(123); // expect error
bound(b); // expect error
function bound2() { }
bound2();
bound2();
bound2(); // expect error
bound2(); // expect error
var x; // error
var y; // ok
var z; // ok
var u; // ok

View file

@ -0,0 +1,35 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveNarrow.ts(9,5): error TS2322: Type '123' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveNarrow.ts(13,7): error TS2339: Property 'toFixed' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveNarrow.ts(21,6): error TS2339: Property 'toString' does not exist on type 'never'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveNarrow.ts (3 errors) ====
class Narrow {
narrowed: boolean
}
var a: object
if (a instanceof Narrow) {
a.narrowed; // ok
a = 123; // error
~
!!! error TS2322: Type '123' is not assignable to type 'object'.
}
if (typeof a === 'number') {
a.toFixed(); // error, never
~~~~~~~
!!! error TS2339: Property 'toFixed' does not exist on type 'never'.
}
var b: object | null
if (typeof b === 'object') {
b.toString(); // ok, object | null
} else {
b.toString(); // error, never
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
}

View file

@ -0,0 +1,46 @@
//// [nonPrimitiveNarrow.ts]
class Narrow {
narrowed: boolean
}
var a: object
if (a instanceof Narrow) {
a.narrowed; // ok
a = 123; // error
}
if (typeof a === 'number') {
a.toFixed(); // error, never
}
var b: object | null
if (typeof b === 'object') {
b.toString(); // ok, object | null
} else {
b.toString(); // error, never
}
//// [nonPrimitiveNarrow.js]
var Narrow = (function () {
function Narrow() {
}
return Narrow;
}());
var a;
if (a instanceof Narrow) {
a.narrowed; // ok
a = 123; // error
}
if (typeof a === 'number') {
a.toFixed(); // error, never
}
var b;
if (typeof b === 'object') {
b.toString(); // ok, object | null
}
else {
b.toString(); // error, never
}

View file

@ -0,0 +1,138 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(7,1): error TS2454: Variable 'a' is used before being assigned.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(8,1): error TS2322: Type 'undefined' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(9,1): error TS2322: Type 'null' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(10,1): error TS2322: Type 'object | null' is not assignable to type 'object'.
Type 'null' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(11,1): error TS2322: Type 'object | undefined' is not assignable to type 'object'.
Type 'undefined' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(12,1): error TS2322: Type 'object | null | undefined' is not assignable to type 'object'.
Type 'undefined' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(18,7): error TS2339: Property 'toString' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(22,5): error TS2322: Type 'object | null' is not assignable to type 'object'.
Type 'null' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(27,5): error TS2531: Object is possibly 'null'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(29,5): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(29,7): error TS2339: Property 'toString' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(33,5): error TS2533: Object is possibly 'null' or 'undefined'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(33,7): error TS2339: Property 'toString' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(39,5): error TS2531: Object is possibly 'null'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(39,7): error TS2339: Property 'toString' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(41,5): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(45,5): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(45,7): error TS2339: Property 'toString' does not exist on type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(47,5): error TS2531: Object is possibly 'null'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(52,14): error TS2344: Type 'number' does not satisfy the constraint 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(53,14): error TS2344: Type 'null' does not satisfy the constraint 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(54,14): error TS2344: Type 'undefined' does not satisfy the constraint 'object'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts (22 errors) ====
var a: object
declare var b: object | null
declare var c: object | undefined
declare var d: object | null | undefined
var e: object | null
a.toString; // error
~
!!! error TS2454: Variable 'a' is used before being assigned.
a = undefined; // error
~
!!! error TS2322: Type 'undefined' is not assignable to type 'object'.
a = null; // error
~
!!! error TS2322: Type 'null' is not assignable to type 'object'.
a = b; // error
~
!!! error TS2322: Type 'object | null' is not assignable to type 'object'.
!!! error TS2322: Type 'null' is not assignable to type 'object'.
a = c; // error
~
!!! error TS2322: Type 'object | undefined' is not assignable to type 'object'.
!!! error TS2322: Type 'undefined' is not assignable to type 'object'.
a = d; // error
~
!!! error TS2322: Type 'object | null | undefined' is not assignable to type 'object'.
!!! error TS2322: Type 'undefined' is not assignable to type 'object'.
e = a; // ok
a = e; // ok
if (typeof b !== 'object') {
b.toString(); // error, never
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
}
if (typeof b === 'object') {
a = b; // error, b is not narrowed
~
!!! error TS2322: Type 'object | null' is not assignable to type 'object'.
!!! error TS2322: Type 'null' is not assignable to type 'object'.
}
if (typeof d === 'object') {
b = d; // ok
d.toString(); // error, object | null
~
!!! error TS2531: Object is possibly 'null'.
} else {
d.toString(); // error, undefined
~
!!! error TS2532: Object is possibly 'undefined'.
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
}
if (d == null) {
d.toString(); // error, undefined | null
~
!!! error TS2533: Object is possibly 'null' or 'undefined'.
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
} else {
d.toString(); // object
}
if (d === null) {
d.toString(); // error, null
~
!!! error TS2531: Object is possibly 'null'.
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
} else {
d.toString(); // error, object | undefined
~
!!! error TS2532: Object is possibly 'undefined'.
}
if (typeof d === 'undefined') {
d.toString(); // error, undefined
~
!!! error TS2532: Object is possibly 'undefined'.
~~~~~~~~
!!! error TS2339: Property 'toString' does not exist on type 'never'.
} else {
d.toString(); // error, object | null
~
!!! error TS2531: Object is possibly 'null'.
}
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
~~~~~~
!!! error TS2344: Type 'number' does not satisfy the constraint 'object'.
var y: Proxy<null>; // error
~~~~
!!! error TS2344: Type 'null' does not satisfy the constraint 'object'.
var z: Proxy<undefined>; // error
~~~~~~~~~
!!! error TS2344: Type 'undefined' does not satisfy the constraint 'object'.
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok

View file

@ -0,0 +1,109 @@
//// [nonPrimitiveStrictNull.ts]
var a: object
declare var b: object | null
declare var c: object | undefined
declare var d: object | null | undefined
var e: object | null
a.toString; // error
a = undefined; // error
a = null; // error
a = b; // error
a = c; // error
a = d; // error
e = a; // ok
a = e; // ok
if (typeof b !== 'object') {
b.toString(); // error, never
}
if (typeof b === 'object') {
a = b; // error, b is not narrowed
}
if (typeof d === 'object') {
b = d; // ok
d.toString(); // error, object | null
} else {
d.toString(); // error, undefined
}
if (d == null) {
d.toString(); // error, undefined | null
} else {
d.toString(); // object
}
if (d === null) {
d.toString(); // error, null
} else {
d.toString(); // error, object | undefined
}
if (typeof d === 'undefined') {
d.toString(); // error, undefined
} else {
d.toString(); // error, object | null
}
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
var y: Proxy<null>; // error
var z: Proxy<undefined>; // error
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok
//// [nonPrimitiveStrictNull.js]
var a;
var e;
a.toString; // error
a = undefined; // error
a = null; // error
a = b; // error
a = c; // error
a = d; // error
e = a; // ok
a = e; // ok
if (typeof b !== 'object') {
b.toString(); // error, never
}
if (typeof b === 'object') {
a = b; // error, b is not narrowed
}
if (typeof d === 'object') {
b = d; // ok
d.toString(); // error, object | null
}
else {
d.toString(); // error, undefined
}
if (d == null) {
d.toString(); // error, undefined | null
}
else {
d.toString(); // object
}
if (d === null) {
d.toString(); // error, null
}
else {
d.toString(); // error, object | undefined
}
if (typeof d === 'undefined') {
d.toString(); // error, undefined
}
else {
d.toString(); // error, object | null
}
var x; // error
var y; // error
var z; // error
var u; // ok

View file

@ -0,0 +1,18 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type '""' is not assignable to type 'object & string'.
Type '""' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(3,1): error TS2322: Type 'string' is not assignable to type 'object & string'.
Type 'string' is not assignable to type 'object'.
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts (2 errors) ====
var a: object & string = ""; // error
~
!!! error TS2322: Type '""' is not assignable to type 'object & string'.
!!! error TS2322: Type '""' is not assignable to type 'object'.
var b: object | string = ""; // ok
a = b; // error
~
!!! error TS2322: Type 'string' is not assignable to type 'object & string'.
!!! error TS2322: Type 'string' is not assignable to type 'object'.
b = a; // ok

View file

@ -0,0 +1,12 @@
//// [nonPrimitiveUnionIntersection.ts]
var a: object & string = ""; // error
var b: object | string = ""; // ok
a = b; // error
b = a; // ok
//// [nonPrimitiveUnionIntersection.js]
var a = ""; // error
var b = ""; // ok
a = b; // error
b = a; // ok

View file

@ -6,9 +6,10 @@ tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,1): error
tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,6): error TS1005: ';' expected.
tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,11): error TS1109: Expression expected.
tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,13): error TS2693: 'I' only refers to a type, but is being used as a value here.
tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(7,6): error TS2457: Type alias name cannot be 'object'
==== tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts (8 errors) ====
==== tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts (9 errors) ====
interface I {}
type any = I;
~~~
@ -30,4 +31,8 @@ tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,13): error
~
!!! error TS1109: Expression expected.
~
!!! error TS2693: 'I' only refers to a type, but is being used as a value here.
!!! error TS2693: 'I' only refers to a type, but is being used as a value here.
type object = I;
~~~~~~
!!! error TS2457: Type alias name cannot be 'object'

View file

@ -4,7 +4,9 @@ type any = I;
type number = I;
type boolean = I;
type string = I;
type void = I;
type void = I;
type object = I;
//// [reservedNamesInAliases.js]
type;

View file

@ -0,0 +1,5 @@
var x = {};
var y = {foo: "bar"};
var a: object;
a = x;
a = y;

View file

@ -0,0 +1,3 @@
var a: object;
a.toString();
a.nonExist(); // error

View file

@ -0,0 +1,7 @@
interface WithNonPrimitive {
foo: object
}
var a: WithNonPrimitive = { foo: {bar: "bar"} };
var b: WithNonPrimitive = {foo: "bar"}; // expect error

View file

@ -0,0 +1,27 @@
var x = {};
var y = {foo: "bar"};
var a: object;
x = a;
y = a; // expect error
a = x;
a = y;
var n = 123;
var b = true;
var s = "fooo";
a = n; // expect error
a = b; // expect error
a = s; // expect error
n = a; // expect error
b = a; // expect error
s = a; // expect error
var numObj: Number = 123;
var boolObj: Boolean = true;
var strObj: String = "string";
a = numObj; // ok
a = boolObj; // ok
a = strObj; // ok

View file

@ -0,0 +1,18 @@
function takeObject(o: object) {}
function returnObject(): object {
return {};
}
var nonPrimitive: object;
var primitive: boolean;
takeObject(nonPrimitive);
nonPrimitive = returnObject();
takeObject(primitive); // expect error
primitive = returnObject(); // expect error
function returnError(): object {
var ret = 123;
return ret; // expect error
}

View file

@ -0,0 +1,35 @@
function generic<T>(t: T) {}
var a = {};
var b = "42";
generic<object>({});
generic<object>(a);
generic<object>(123); // expect error
generic<object>(b); // expect error
function bound<T extends object>(t: T) {}
bound({});
bound(a);
bound(123); // expect error
bound(b); // expect error
function bound2<T extends object>() {}
bound2<{}>();
bound2<Object>();
bound2<number>(); // expect error
bound2<string>(); // expect error
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
var y: Proxy<null>; // ok
var z: Proxy<undefined> ; // ok
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok

View file

@ -0,0 +1,22 @@
class Narrow {
narrowed: boolean
}
var a: object
if (a instanceof Narrow) {
a.narrowed; // ok
a = 123; // error
}
if (typeof a === 'number') {
a.toFixed(); // error, never
}
var b: object | null
if (typeof b === 'object') {
b.toString(); // ok, object | null
} else {
b.toString(); // error, never
}

View file

@ -0,0 +1,61 @@
// @strictNullChecks: true
var a: object
declare var b: object | null
declare var c: object | undefined
declare var d: object | null | undefined
var e: object | null
a.toString; // error
a = undefined; // error
a = null; // error
a = b; // error
a = c; // error
a = d; // error
e = a; // ok
a = e; // ok
if (typeof b !== 'object') {
b.toString(); // error, never
}
if (typeof b === 'object') {
a = b; // error, b is not narrowed
}
if (typeof d === 'object') {
b = d; // ok
d.toString(); // error, object | null
} else {
d.toString(); // error, undefined
}
if (d == null) {
d.toString(); // error, undefined | null
} else {
d.toString(); // object
}
if (d === null) {
d.toString(); // error, null
} else {
d.toString(); // error, object | undefined
}
if (typeof d === 'undefined') {
d.toString(); // error, undefined
} else {
d.toString(); // error, object | null
}
interface Proxy<T extends object> {}
var x: Proxy<number>; // error
var y: Proxy<null>; // error
var z: Proxy<undefined>; // error
interface Blah {
foo: number;
}
var u: Proxy<Blah>; // ok

View file

@ -0,0 +1,4 @@
var a: object & string = ""; // error
var b: object | string = ""; // ok
a = b; // error
b = a; // ok

View file

@ -3,4 +3,5 @@ type any = I;
type number = I;
type boolean = I;
type string = I;
type void = I;
type void = I;
type object = I;