diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a6f5993f6c8..4b7d1d7b274 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3145,6 +3145,7 @@ namespace ts { case SyntaxKind.AnyKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.NeverKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.SymbolKeyword: @@ -3343,6 +3344,7 @@ namespace ts { case SyntaxKind.NumberKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.StringKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.SymbolKeyword: case SyntaxKind.VoidKeyword: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a27e8ba524d..39832dfcb35 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -146,6 +146,7 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const nonPrimitiveType = createNonPrimitiveType(); const emptyTypeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral | SymbolFlags.Transient, "__type"); emptyTypeLiteralSymbol.members = createMap(); @@ -1684,6 +1685,14 @@ namespace ts { return type; } + function createNonPrimitiveType(): NonPrimitiveType { + const type = setStructuredTypeMembers( + createObjectType(ObjectFlags.NonPrimitive, undefined), + emptySymbols, emptyArray, emptyArray, undefined, undefined); + type.intrinsicName = "object"; + return type; + } + function createObjectType(objectFlags: ObjectFlags, symbol?: Symbol): ObjectType { const type = createType(TypeFlags.Object); type.objectFlags = objectFlags; @@ -4178,6 +4187,7 @@ namespace ts { case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.SymbolKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NullKeyword: @@ -6384,6 +6394,8 @@ namespace ts { return nullType; case SyntaxKind.NeverKeyword: return neverType; + case SyntaxKind.ObjectKeyword: + return nonPrimitiveType; case SyntaxKind.JSDocNullKeyword: return nullType; case SyntaxKind.JSDocUndefinedKeyword: @@ -7139,6 +7151,7 @@ namespace ts { if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && isEnumTypeRelatedTo(source, 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 && (source).objectFlags & ObjectFlags.NonPrimitive && target.flags & TypeFlags.Primitive) 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; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 82302e98e37..ad8781aecec 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -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, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1ee59149b2c..db919b56449 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -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 @@ -2857,6 +2859,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 }