From 2ed572af9c43faf4070200a2e51d337d371080cb Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Fri, 25 Nov 2016 18:54:01 +0800 Subject: [PATCH] Fix #1809, introduce non primitive type --- src/compiler/binder.ts | 2 ++ src/compiler/checker.ts | 13 +++++++++++++ src/compiler/scanner.ts | 1 + src/compiler/types.ts | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index c2bfce10e57d6..ae6825de4a36b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3168,6 +3168,7 @@ namespace ts { case SyntaxKind.AnyKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.NeverKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.SymbolKeyword: @@ -3366,6 +3367,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 6d5a8b74cb3bd..f5977ba5a78a8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -144,6 +144,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(); @@ -1662,6 +1663,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; @@ -4120,6 +4129,7 @@ namespace ts { case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.SymbolKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NullKeyword: @@ -6257,6 +6267,8 @@ namespace ts { return nullType; case SyntaxKind.NeverKeyword: return neverType; + case SyntaxKind.ObjectKeyword: + return nonPrimitiveType; case SyntaxKind.JSDocNullKeyword: return nullType; case SyntaxKind.JSDocUndefinedKeyword: @@ -7004,6 +7016,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 82302e98e37a8..ad8781aecec16 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 219e7efa90a23..cba2e986a8e97 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -175,6 +175,7 @@ namespace ts { ReadonlyKeyword, RequireKeyword, NumberKeyword, + ObjectKeyword, SetKeyword, StringKeyword, SymbolKeyword, @@ -822,6 +823,7 @@ namespace ts { export interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword @@ -2861,6 +2863,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 } @@ -2969,6 +2972,11 @@ namespace ts { iteratorElementType?: Type; } + // an non primitive type is equivalent to {} minus primitive types + export interface NonPrimitiveType extends ResolvedType, IntrinsicType { + intrinsicName: "object"; + } + // Type parameters (TypeFlags.TypeParameter) export interface TypeParameter extends Type { constraint: Type; // Constraint