From 15dcccde7ddbbb3626a3e3c2d5a53fe27650196a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 24 Jan 2015 08:03:29 -0800 Subject: [PATCH 1/3] Improved subtype compatibility for types of object literals --- src/compiler/checker.ts | 73 ++++++++++++++++++++--------------------- src/compiler/types.ts | 5 ++- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7233c2e85d5..431d81696a1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -66,8 +66,8 @@ module ts { var numberType = createIntrinsicType(TypeFlags.Number, "number"); var booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean"); var voidType = createIntrinsicType(TypeFlags.Void, "void"); - var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.Unwidened, "undefined"); - var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.Unwidened, "null"); + var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefined, "undefined"); + var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefined, "null"); var unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); var resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__"); @@ -2807,15 +2807,19 @@ module ts { } } - function getUnwidenedFlagOfTypes(types: Type[]): TypeFlags { - return forEach(types, t => t.flags & TypeFlags.Unwidened) || 0; + function getWideningFlagsOfTypes(types: Type[]): TypeFlags { + var result: TypeFlags = 0; + for (var i = 0; i < types.length; i++) { + result |= types[i].flags; + } + return result & TypeFlags.RequiresWidening; } function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { var id = getTypeListId(typeArguments); var type = target.instantiations[id]; if (!type) { - var flags = TypeFlags.Reference | getUnwidenedFlagOfTypes(typeArguments); + var flags = TypeFlags.Reference | getWideningFlagsOfTypes(typeArguments); type = target.instantiations[id] = createObjectType(flags, target.symbol); type.target = target; type.typeArguments = typeArguments; @@ -3076,7 +3080,7 @@ module ts { var id = getTypeListId(sortedTypes); var type = unionTypes[id]; if (!type) { - type = unionTypes[id] = createObjectType(TypeFlags.Union | getUnwidenedFlagOfTypes(sortedTypes)); + type = unionTypes[id] = createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(sortedTypes)); type.types = sortedTypes; } return type; @@ -3692,12 +3696,13 @@ module ts { } var result = Ternary.True; var properties = getPropertiesOfObjectType(target); + var requireOptionalProperties = relation === subtypeRelation && !(source.flags & TypeFlags.ObjectLiteral); for (var i = 0; i < properties.length; i++) { var targetProp = properties[i]; var sourceProp = getPropertyOfType(source, targetProp.name); if (sourceProp !== targetProp) { if (!sourceProp) { - if (relation === subtypeRelation || !(targetProp.flags & SymbolFlags.Optional)) { + if (!(targetProp.flags & SymbolFlags.Optional) || requireOptionalProperties) { if (reportErrors) { reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source)); } @@ -4088,10 +4093,6 @@ module ts { errorMessageChainHead); } - function isTypeOfObjectLiteral(type: Type): boolean { - return (type.flags & TypeFlags.Anonymous) && type.symbol && (type.symbol.flags & SymbolFlags.ObjectLiteral) ? true : false; - } - function isArrayType(type: Type): boolean { return type.flags & TypeFlags.Reference && (type).target === globalArrayType; } @@ -4104,13 +4105,18 @@ module ts { var properties = getPropertiesOfObjectType(type); var members: SymbolTable = {}; forEach(properties, p => { - var symbol = createSymbol(p.flags | SymbolFlags.Transient, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = getWidenedType(getTypeOfSymbol(p)); - symbol.target = p; - if (p.valueDeclaration) symbol.valueDeclaration = p.valueDeclaration; - members[symbol.name] = symbol; + var propType = getTypeOfSymbol(p); + var widenedType = getWidenedType(propType); + if (propType !== widenedType) { + var symbol = createSymbol(p.flags | SymbolFlags.Transient, p.name); + symbol.declarations = p.declarations; + symbol.parent = p.parent; + symbol.type = getWidenedType(getTypeOfSymbol(p)); + symbol.target = p; + if (p.valueDeclaration) symbol.valueDeclaration = p.valueDeclaration; + p = symbol; + } + members[p.name] = p; }); var stringIndexType = getIndexTypeOfType(type, IndexKind.String); var numberIndexType = getIndexTypeOfType(type, IndexKind.Number); @@ -4120,16 +4126,16 @@ module ts { } function getWidenedType(type: Type): Type { - if (type.flags & TypeFlags.Unwidened) { + if (type.flags & TypeFlags.RequiresWidening) { if (type.flags & (TypeFlags.Undefined | TypeFlags.Null)) { return anyType; } + if (type.flags & TypeFlags.ObjectLiteral) { + return getWidenedTypeOfObjectLiteral(type); + } if (type.flags & TypeFlags.Union) { return getUnionType(map((type).types, getWidenedType)); } - if (isTypeOfObjectLiteral(type)) { - return getWidenedTypeOfObjectLiteral(type); - } if (isArrayType(type)) { return createArrayType(getWidenedType((type).typeArguments[0])); } @@ -4150,11 +4156,11 @@ module ts { if (isArrayType(type)) { return reportWideningErrorsInType((type).typeArguments[0]); } - if (isTypeOfObjectLiteral(type)) { + if (type.flags & TypeFlags.ObjectLiteral) { var errorReported = false; forEach(getPropertiesOfObjectType(type), p => { var t = getTypeOfSymbol(p); - if (t.flags & TypeFlags.Unwidened) { + if (t.flags & TypeFlags.ContainsUndefined) { if (!reportWideningErrorsInType(t)) { error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t))); } @@ -4198,7 +4204,7 @@ module ts { } function reportErrorsFromWidening(declaration: Declaration, type: Type) { - if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.Unwidened) { + if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefined) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAnyError(declaration, type); @@ -5455,21 +5461,10 @@ module ts { } } - // If object literal is contextually (but not inferentially) typed, copy missing optional properties from - // the contextual type such that the resulting type becomes a subtype in cases where only optional properties - // were omitted. There is no need to create new property objects as nothing in them needs to change. - if (contextualType && !isInferentialContext(contextualMapper)) { - forEach(getPropertiesOfObjectType(contextualType), p => { - if (p.flags & SymbolFlags.Optional && !hasProperty(properties, p.name)) { - properties[p.name] = p; - } - }); - } - var stringIndexType = getIndexType(IndexKind.String); var numberIndexType = getIndexType(IndexKind.Number); var result = createAnonymousType(node.symbol, properties, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= (typeFlags & TypeFlags.Unwidened); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsLiteral | (typeFlags & TypeFlags.ContainsUndefined); return result; function getIndexType(kind: IndexKind) { @@ -5485,7 +5480,9 @@ module ts { } } } - return propTypes.length ? getUnionType(propTypes) : undefinedType; + var result = propTypes.length ? getUnionType(propTypes) : undefinedType; + typeFlags |= result.flags; + return result; } return undefined; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b8c842641d7..474fdf30fed 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1283,12 +1283,15 @@ module ts { Union = 0x00004000, // Union Anonymous = 0x00008000, // Anonymous FromSignature = 0x00010000, // Created for signature assignment check - Unwidened = 0x00020000, // Unwidened type (is or contains Undefined or Null type) + ObjectLiteral = 0x00020000, // Originates in an object literal + ContainsUndefined = 0x00040000, // Type is or contains Undefined or Null type + ContainsLiteral = 0x00080000, // Type is or contains object literal type Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null, StringLike = String | StringLiteral, NumberLike = Number | Enum, ObjectType = Class | Interface | Reference | Tuple | Anonymous, + RequiresWidening = ContainsUndefined | ContainsLiteral } // Properties common to all types From d6eb486c3ad424bcc101733cb23893ce1ab51e2a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 24 Jan 2015 08:04:23 -0800 Subject: [PATCH 2/3] Accepting new baselines --- .../baselines/reference/arrayCast.errors.txt | 2 ++ .../reference/assignmentCompatBug2.errors.txt | 16 +++++++------- .../assignmentCompatWithObjectMembers3.types | 4 ++-- .../reference/assignmentCompatability1.types | 2 +- .../reference/assignmentCompatability2.types | 2 +- .../reference/assignmentCompatability3.types | 2 +- .../reference/assignmentCompatability4.types | 2 +- .../reference/assignmentCompatability5.types | 2 +- .../reference/assignmentCompatability6.types | 4 ++-- .../reference/assignmentCompatability7.types | 4 ++-- .../reference/assignmentCompatability8.types | 2 +- .../reference/assignmentCompatability9.types | 2 +- .../reference/getterSetterNonAccessor.types | 4 ++-- tests/baselines/reference/indexer2.errors.txt | 20 ------------------ tests/baselines/reference/indexer2.types | 21 +++++++++++++++++++ .../baselines/reference/indexer2A.errors.txt | 15 ++----------- .../reference/intTypeCheck.errors.txt | 8 +++---- .../reference/interfaceContextualType.types | 12 +++++------ .../reference/objectLitGetterSetter.types | 4 ++-- .../objectLiteralContextualTyping.types | 4 ++-- .../optionalAccessorsInInterface1.types | 4 ++-- .../optionalPropertiesTest.errors.txt | 8 +++---- ...adBindingAcrossDeclarationBoundaries.types | 6 +++--- ...dBindingAcrossDeclarationBoundaries2.types | 6 +++--- ...notationBestCommonTypeInArrayLiteral.types | 6 +++--- .../baselines/reference/underscoreTest1.types | 6 +++--- 26 files changed, 80 insertions(+), 88 deletions(-) delete mode 100644 tests/baselines/reference/indexer2.errors.txt create mode 100644 tests/baselines/reference/indexer2.types diff --git a/tests/baselines/reference/arrayCast.errors.txt b/tests/baselines/reference/arrayCast.errors.txt index 53be1c903a3..10562cc57e4 100644 --- a/tests/baselines/reference/arrayCast.errors.txt +++ b/tests/baselines/reference/arrayCast.errors.txt @@ -1,5 +1,6 @@ tests/cases/compiler/arrayCast.ts(3,1): error TS2352: Neither type '{ foo: string; }[]' nor type '{ id: number; }[]' is assignable to the other. Type '{ foo: string; }' is not assignable to type '{ id: number; }'. + Property 'id' is missing in type '{ foo: string; }'. ==== tests/cases/compiler/arrayCast.ts (1 errors) ==== @@ -9,6 +10,7 @@ tests/cases/compiler/arrayCast.ts(3,1): error TS2352: Neither type '{ foo: strin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Neither type '{ foo: string; }[]' nor type '{ id: number; }[]' is assignable to the other. !!! error TS2352: Type '{ foo: string; }' is not assignable to type '{ id: number; }'. +!!! error TS2352: Property 'id' is missing in type '{ foo: string; }'. // Should succeed, as the {} element causes the type of the array to be {}[] <{ id: number; }[]>[{ foo: "s" }, {}]; \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatBug2.errors.txt b/tests/baselines/reference/assignmentCompatBug2.errors.txt index b90c470d771..15bf1111391 100644 --- a/tests/baselines/reference/assignmentCompatBug2.errors.txt +++ b/tests/baselines/reference/assignmentCompatBug2.errors.txt @@ -2,10 +2,10 @@ tests/cases/compiler/assignmentCompatBug2.ts(1,5): error TS2322: Type '{ a: numb Property 'b' is missing in type '{ a: number; }'. tests/cases/compiler/assignmentCompatBug2.ts(3,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'. Property 'b' is missing in type '{ a: number; }'. -tests/cases/compiler/assignmentCompatBug2.ts(15,1): error TS2322: Type '{ f: (n: number) => number; g: (s: string) => number; n?: number; k?(a: any): any; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. - Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; n?: number; k?(a: any): any; }'. -tests/cases/compiler/assignmentCompatBug2.ts(20,1): error TS2322: Type '{ f: (n: number) => number; m: number; n?: number; k?(a: any): any; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. - Property 'g' is missing in type '{ f: (n: number) => number; m: number; n?: number; k?(a: any): any; }'. +tests/cases/compiler/assignmentCompatBug2.ts(15,1): error TS2322: Type '{ f: (n: number) => number; g: (s: string) => number; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. + Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; }'. +tests/cases/compiler/assignmentCompatBug2.ts(20,1): error TS2322: Type '{ f: (n: number) => number; m: number; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. + Property 'g' is missing in type '{ f: (n: number) => number; m: number; }'. tests/cases/compiler/assignmentCompatBug2.ts(33,1): error TS2322: Type '{ f: (n: number) => number; g: (s: string) => number; n: number; k: (a: any) => any; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; n: number; k: (a: any) => any; }'. @@ -33,16 +33,16 @@ tests/cases/compiler/assignmentCompatBug2.ts(33,1): error TS2322: Type '{ f: (n: b3 = { ~~ -!!! error TS2322: Type '{ f: (n: number) => number; g: (s: string) => number; n?: number; k?(a: any): any; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. -!!! error TS2322: Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; n?: number; k?(a: any): any; }'. +!!! error TS2322: Type '{ f: (n: number) => number; g: (s: string) => number; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. +!!! error TS2322: Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; }'. f: (n) => { return 0; }, g: (s) => { return 0; }, }; // error b3 = { ~~ -!!! error TS2322: Type '{ f: (n: number) => number; m: number; n?: number; k?(a: any): any; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. -!!! error TS2322: Property 'g' is missing in type '{ f: (n: number) => number; m: number; n?: number; k?(a: any): any; }'. +!!! error TS2322: Type '{ f: (n: number) => number; m: number; }' is not assignable to type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'. +!!! error TS2322: Property 'g' is missing in type '{ f: (n: number) => number; m: number; }'. f: (n) => { return 0; }, m: 0, }; // error diff --git a/tests/baselines/reference/assignmentCompatWithObjectMembers3.types b/tests/baselines/reference/assignmentCompatWithObjectMembers3.types index ff7ef23307d..85a7e59ffbc 100644 --- a/tests/baselines/reference/assignmentCompatWithObjectMembers3.types +++ b/tests/baselines/reference/assignmentCompatWithObjectMembers3.types @@ -51,13 +51,13 @@ var b: { foo: string; baz?: string } var a2: S2 = { foo: '' }; >a2 : S2 >S2 : S2 ->{ foo: '' } : { foo: string; bar?: string; } +>{ foo: '' } : { foo: string; } >foo : string var b2: T2 = { foo: '' }; >b2 : T2 >T2 : T2 ->{ foo: '' } : { foo: string; baz?: string; } +>{ foo: '' } : { foo: string; } >foo : string s = t; diff --git a/tests/baselines/reference/assignmentCompatability1.types b/tests/baselines/reference/assignmentCompatability1.types index 8bb4301b201..9949fc14bf5 100644 --- a/tests/baselines/reference/assignmentCompatability1.types +++ b/tests/baselines/reference/assignmentCompatability1.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability2.types b/tests/baselines/reference/assignmentCompatability2.types index 69a20b34dd7..16da45c7e35 100644 --- a/tests/baselines/reference/assignmentCompatability2.types +++ b/tests/baselines/reference/assignmentCompatability2.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability3.types b/tests/baselines/reference/assignmentCompatability3.types index 4b598fba84c..61279b9c7fa 100644 --- a/tests/baselines/reference/assignmentCompatability3.types +++ b/tests/baselines/reference/assignmentCompatability3.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability4.types b/tests/baselines/reference/assignmentCompatability4.types index 3d8e776ff72..f7e5801e9b3 100644 --- a/tests/baselines/reference/assignmentCompatability4.types +++ b/tests/baselines/reference/assignmentCompatability4.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability5.types b/tests/baselines/reference/assignmentCompatability5.types index 970c913955d..80eda3e510b 100644 --- a/tests/baselines/reference/assignmentCompatability5.types +++ b/tests/baselines/reference/assignmentCompatability5.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability6.types b/tests/baselines/reference/assignmentCompatability6.types index cf131600c41..5e9ae8c6a2f 100644 --- a/tests/baselines/reference/assignmentCompatability6.types +++ b/tests/baselines/reference/assignmentCompatability6.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; @@ -29,7 +29,7 @@ module __test2__ { >T : T >obj3 : interfaceWithOptional >interfaceWithOptional : interfaceWithOptional ->{ } : { one?: number; } +>{ } : {} export var __val__obj3 = obj3; >__val__obj3 : interfaceWithOptional diff --git a/tests/baselines/reference/assignmentCompatability7.types b/tests/baselines/reference/assignmentCompatability7.types index 5bb46428314..b7b2ab70566 100644 --- a/tests/baselines/reference/assignmentCompatability7.types +++ b/tests/baselines/reference/assignmentCompatability7.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; @@ -32,7 +32,7 @@ module __test2__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability8.types b/tests/baselines/reference/assignmentCompatability8.types index 21fa300a37d..1c009eea482 100644 --- a/tests/baselines/reference/assignmentCompatability8.types +++ b/tests/baselines/reference/assignmentCompatability8.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/assignmentCompatability9.types b/tests/baselines/reference/assignmentCompatability9.types index cc8df0387e7..a8235220bec 100644 --- a/tests/baselines/reference/assignmentCompatability9.types +++ b/tests/baselines/reference/assignmentCompatability9.types @@ -12,7 +12,7 @@ module __test1__ { >U : U >obj4 : interfaceWithPublicAndOptional >interfaceWithPublicAndOptional : interfaceWithPublicAndOptional ->{ one: 1 } : { one: number; two?: string; } +>{ one: 1 } : { one: number; } >one : number export var __val__obj4 = obj4; diff --git a/tests/baselines/reference/getterSetterNonAccessor.types b/tests/baselines/reference/getterSetterNonAccessor.types index 0c1be481b3a..f3e5d549cff 100644 --- a/tests/baselines/reference/getterSetterNonAccessor.types +++ b/tests/baselines/reference/getterSetterNonAccessor.types @@ -14,8 +14,8 @@ Object.defineProperty({}, "0", ({ >{} : {} >({ get: getFunc, set: setFunc, configurable: true }) : PropertyDescriptor >PropertyDescriptor : PropertyDescriptor ->({ get: getFunc, set: setFunc, configurable: true }) : { get: () => any; set: (v: any) => void; configurable: boolean; enumerable?: boolean; value?: any; writable?: boolean; } ->{ get: getFunc, set: setFunc, configurable: true } : { get: () => any; set: (v: any) => void; configurable: boolean; enumerable?: boolean; value?: any; writable?: boolean; } +>({ get: getFunc, set: setFunc, configurable: true }) : { get: () => any; set: (v: any) => void; configurable: boolean; } +>{ get: getFunc, set: setFunc, configurable: true } : { get: () => any; set: (v: any) => void; configurable: boolean; } get: getFunc, >get : () => any diff --git a/tests/baselines/reference/indexer2.errors.txt b/tests/baselines/reference/indexer2.errors.txt deleted file mode 100644 index 28020a570ed..00000000000 --- a/tests/baselines/reference/indexer2.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/indexer2.ts(6,25): error TS2352: Neither type '{ [x: number]: undefined; }' nor type 'IDirectChildrenMap' is assignable to the other. - Types of property 'hasOwnProperty' are incompatible. - Type '(v: string) => boolean' is not assignable to type '(objectId: number) => boolean'. - Types of parameters 'v' and 'objectId' are incompatible. - Type 'string' is not assignable to type 'number'. - - -==== tests/cases/compiler/indexer2.ts (1 errors) ==== - interface IHeapObjectProperty {} - interface IDirectChildrenMap { - hasOwnProperty(objectId: number) : boolean; - [objectId: number] : IHeapObjectProperty[]; - } - var directChildrenMap = {}; - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2352: Neither type '{ [x: number]: undefined; }' nor type 'IDirectChildrenMap' is assignable to the other. -!!! error TS2352: Types of property 'hasOwnProperty' are incompatible. -!!! error TS2352: Type '(v: string) => boolean' is not assignable to type '(objectId: number) => boolean'. -!!! error TS2352: Types of parameters 'v' and 'objectId' are incompatible. -!!! error TS2352: Type 'string' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/indexer2.types b/tests/baselines/reference/indexer2.types new file mode 100644 index 00000000000..7f1ccd41cb5 --- /dev/null +++ b/tests/baselines/reference/indexer2.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/indexer2.ts === +interface IHeapObjectProperty {} +>IHeapObjectProperty : IHeapObjectProperty + +interface IDirectChildrenMap { +>IDirectChildrenMap : IDirectChildrenMap + + hasOwnProperty(objectId: number) : boolean; +>hasOwnProperty : (objectId: number) => boolean +>objectId : number + + [objectId: number] : IHeapObjectProperty[]; +>objectId : number +>IHeapObjectProperty : IHeapObjectProperty +} +var directChildrenMap = {}; +>directChildrenMap : IDirectChildrenMap +>{} : IDirectChildrenMap +>IDirectChildrenMap : IDirectChildrenMap +>{} : { [x: number]: undefined; } + diff --git a/tests/baselines/reference/indexer2A.errors.txt b/tests/baselines/reference/indexer2A.errors.txt index f2314c5b49b..adf90fb743f 100644 --- a/tests/baselines/reference/indexer2A.errors.txt +++ b/tests/baselines/reference/indexer2A.errors.txt @@ -1,12 +1,7 @@ tests/cases/compiler/indexer2A.ts(4,5): error TS2391: Function implementation is missing or not immediately following the declaration. -tests/cases/compiler/indexer2A.ts(7,25): error TS2352: Neither type '{ [x: number]: undefined; }' nor type 'IDirectChildrenMap' is assignable to the other. - Types of property 'hasOwnProperty' are incompatible. - Type '(v: string) => boolean' is not assignable to type '(objectId: number) => boolean'. - Types of parameters 'v' and 'objectId' are incompatible. - Type 'string' is not assignable to type 'number'. -==== tests/cases/compiler/indexer2A.ts (2 errors) ==== +==== tests/cases/compiler/indexer2A.ts (1 errors) ==== class IHeapObjectProperty { } class IDirectChildrenMap { // Decided to enforce a semicolon after declarations @@ -15,10 +10,4 @@ tests/cases/compiler/indexer2A.ts(7,25): error TS2352: Neither type '{ [x: numbe !!! error TS2391: Function implementation is missing or not immediately following the declaration. [objectId: number]: IHeapObjectProperty[] } - var directChildrenMap = {}; - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2352: Neither type '{ [x: number]: undefined; }' nor type 'IDirectChildrenMap' is assignable to the other. -!!! error TS2352: Types of property 'hasOwnProperty' are incompatible. -!!! error TS2352: Type '(v: string) => boolean' is not assignable to type '(objectId: number) => boolean'. -!!! error TS2352: Types of parameters 'v' and 'objectId' are incompatible. -!!! error TS2352: Type 'string' is not assignable to type 'number'. \ No newline at end of file + var directChildrenMap = {}; \ No newline at end of file diff --git a/tests/baselines/reference/intTypeCheck.errors.txt b/tests/baselines/reference/intTypeCheck.errors.txt index 237a4b8e7f2..5f7c213a916 100644 --- a/tests/baselines/reference/intTypeCheck.errors.txt +++ b/tests/baselines/reference/intTypeCheck.errors.txt @@ -39,8 +39,8 @@ tests/cases/compiler/intTypeCheck.ts(146,5): error TS2322: Type 'boolean' is not tests/cases/compiler/intTypeCheck.ts(146,21): error TS1109: Expression expected. tests/cases/compiler/intTypeCheck.ts(146,22): error TS2304: Cannot find name 'i4'. tests/cases/compiler/intTypeCheck.ts(147,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/compiler/intTypeCheck.ts(152,5): error TS2322: Type '{ p1?: any; p2?: string; p4?(): any; p5?(): void; p7?(pa1: any, pa2: any): void; }' is not assignable to type 'i5'. - Property 'p' is missing in type '{ p1?: any; p2?: string; p4?(): any; p5?(): void; p7?(pa1: any, pa2: any): void; }'. +tests/cases/compiler/intTypeCheck.ts(152,5): error TS2322: Type '{}' is not assignable to type 'i5'. + Property 'p' is missing in type '{}'. tests/cases/compiler/intTypeCheck.ts(153,5): error TS2322: Type 'Object' is not assignable to type 'i5'. Property 'p' is missing in type 'Object'. tests/cases/compiler/intTypeCheck.ts(154,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. @@ -313,8 +313,8 @@ tests/cases/compiler/intTypeCheck.ts(203,17): error TS2351: Cannot use 'new' wit var obj44: i5; var obj45: i5 = {}; ~~~~~ -!!! error TS2322: Type '{ p1?: any; p2?: string; p4?(): any; p5?(): void; p7?(pa1: any, pa2: any): void; }' is not assignable to type 'i5'. -!!! error TS2322: Property 'p' is missing in type '{ p1?: any; p2?: string; p4?(): any; p5?(): void; p7?(pa1: any, pa2: any): void; }'. +!!! error TS2322: Type '{}' is not assignable to type 'i5'. +!!! error TS2322: Property 'p' is missing in type '{}'. var obj46: i5 = new Object(); ~~~~~ !!! error TS2322: Type 'Object' is not assignable to type 'i5'. diff --git a/tests/baselines/reference/interfaceContextualType.types b/tests/baselines/reference/interfaceContextualType.types index 412a48cfbda..3078ecfdfa4 100644 --- a/tests/baselines/reference/interfaceContextualType.types +++ b/tests/baselines/reference/interfaceContextualType.types @@ -34,27 +34,27 @@ class Bug { >{} : { [x: string]: undefined; } this.values['comments'] = { italic: true }; ->this.values['comments'] = { italic: true } : { italic: boolean; bold?: boolean; } +>this.values['comments'] = { italic: true } : { italic: boolean; } >this.values['comments'] : IOptions >this.values : IMap >this : Bug >values : IMap ->{ italic: true } : { italic: boolean; bold?: boolean; } +>{ italic: true } : { italic: boolean; } >italic : boolean } shouldBeOK() { >shouldBeOK : () => void this.values = { ->this.values = { comments: { italic: true } } : { [x: string]: { italic: boolean; bold?: boolean; }; comments: { italic: boolean; bold?: boolean; }; } +>this.values = { comments: { italic: true } } : { [x: string]: { italic: boolean; }; comments: { italic: boolean; }; } >this.values : IMap >this : Bug >values : IMap ->{ comments: { italic: true } } : { [x: string]: { italic: boolean; bold?: boolean; }; comments: { italic: boolean; bold?: boolean; }; } +>{ comments: { italic: true } } : { [x: string]: { italic: boolean; }; comments: { italic: boolean; }; } comments: { italic: true } ->comments : { italic: boolean; bold?: boolean; } ->{ italic: true } : { italic: boolean; bold?: boolean; } +>comments : { italic: boolean; } +>{ italic: true } : { italic: boolean; } >italic : boolean }; diff --git a/tests/baselines/reference/objectLitGetterSetter.types b/tests/baselines/reference/objectLitGetterSetter.types index bbb7ee10140..92decfd4068 100644 --- a/tests/baselines/reference/objectLitGetterSetter.types +++ b/tests/baselines/reference/objectLitGetterSetter.types @@ -11,8 +11,8 @@ >obj : {} >({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : PropertyDescriptor >PropertyDescriptor : PropertyDescriptor ->({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : { get: () => number; set: (v: any) => void; configurable?: boolean; enumerable?: boolean; value?: any; writable?: boolean; } ->{ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } } : { get: () => number; set: (v: any) => void; configurable?: boolean; enumerable?: boolean; value?: any; writable?: boolean; } +>({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : { get: () => number; set: (v: any) => void; } +>{ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } } : { get: () => number; set: (v: any) => void; } get: function () { >get : () => number diff --git a/tests/baselines/reference/objectLiteralContextualTyping.types b/tests/baselines/reference/objectLiteralContextualTyping.types index 495e8df1438..32c9e91b2c7 100644 --- a/tests/baselines/reference/objectLiteralContextualTyping.types +++ b/tests/baselines/reference/objectLiteralContextualTyping.types @@ -24,7 +24,7 @@ var x = foo({ name: "Sprocket" }); >x : string >foo({ name: "Sprocket" }) : string >foo : { (item: Item): string; (item: any): number; } ->{ name: "Sprocket" } : { name: string; description?: string; } +>{ name: "Sprocket" } : { name: string; } >name : string var x: string; @@ -74,7 +74,7 @@ var b = bar({}); >b : {} >bar({}) : {} >bar : (param: { x?: T; }) => T ->{} : { x?: {}; } +>{} : {} var b: {}; >b : {} diff --git a/tests/baselines/reference/optionalAccessorsInInterface1.types b/tests/baselines/reference/optionalAccessorsInInterface1.types index f1dcd854f75..c426cdba178 100644 --- a/tests/baselines/reference/optionalAccessorsInInterface1.types +++ b/tests/baselines/reference/optionalAccessorsInInterface1.types @@ -21,7 +21,7 @@ defineMyProperty({}, "name", { get: function () { return 5; } }); >defineMyProperty({}, "name", { get: function () { return 5; } }) : any >defineMyProperty : (o: any, p: string, attributes: MyPropertyDescriptor) => any >{} : {} ->{ get: function () { return 5; } } : { get: () => number; set?(v: any): void; } +>{ get: function () { return 5; } } : { get: () => number; } >get : () => number >function () { return 5; } : () => number @@ -47,7 +47,7 @@ defineMyProperty2({}, "name", { get: function () { return 5; } }); >defineMyProperty2({}, "name", { get: function () { return 5; } }) : any >defineMyProperty2 : (o: any, p: string, attributes: MyPropertyDescriptor2) => any >{} : {} ->{ get: function () { return 5; } } : { get: () => number; set?: (v: any) => void; } +>{ get: function () { return 5; } } : { get: () => number; } >get : () => number >function () { return 5; } : () => number diff --git a/tests/baselines/reference/optionalPropertiesTest.errors.txt b/tests/baselines/reference/optionalPropertiesTest.errors.txt index a904911e232..a4b721e92ef 100644 --- a/tests/baselines/reference/optionalPropertiesTest.errors.txt +++ b/tests/baselines/reference/optionalPropertiesTest.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/optionalPropertiesTest.ts(14,1): error TS2322: Type '{ name: string; print?(): void; }' is not assignable to type 'IFoo'. - Property 'id' is missing in type '{ name: string; print?(): void; }'. +tests/cases/compiler/optionalPropertiesTest.ts(14,1): error TS2322: Type '{ name: string; }' is not assignable to type 'IFoo'. + Property 'id' is missing in type '{ name: string; }'. tests/cases/compiler/optionalPropertiesTest.ts(25,5): error TS2322: Type '{}' is not assignable to type 'i1'. Property 'M' is missing in type '{}'. tests/cases/compiler/optionalPropertiesTest.ts(26,5): error TS2322: Type '{}' is not assignable to type 'i3'. @@ -24,8 +24,8 @@ tests/cases/compiler/optionalPropertiesTest.ts(40,1): error TS2322: Type 'i2' is foo = { id: 1234, name: "test" }; // Ok foo = { name: "test" }; // Error, id missing ~~~ -!!! error TS2322: Type '{ name: string; print?(): void; }' is not assignable to type 'IFoo'. -!!! error TS2322: Property 'id' is missing in type '{ name: string; print?(): void; }'. +!!! error TS2322: Type '{ name: string; }' is not assignable to type 'IFoo'. +!!! error TS2322: Property 'id' is missing in type '{ name: string; }'. foo = {id: 1234, print:()=>{}} // Ok var s = foo.name || "default"; diff --git a/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries.types b/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries.types index f597c93bdda..311cf971b61 100644 --- a/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries.types +++ b/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries.types @@ -105,17 +105,17 @@ var a1 = a.a({}); >a.a : { (o: Opt1): Opt1; (o: Opt2): Opt2; (o: Opt3): Opt3; (o: Opt4): Opt4; } >a : A >a : { (o: Opt1): Opt1; (o: Opt2): Opt2; (o: Opt3): Opt3; (o: Opt4): Opt4; } ->{} : { r?: any; } +>{} : {} var a1 = a({}); >a1 : Opt3 >a({}) : Opt3 >a : A ->{} : { r?: any; } +>{} : {} var a1 = new a({}); >a1 : Opt3 >new a({}) : Opt3 >a : A ->{} : { r?: any; } +>{} : {} diff --git a/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries2.types b/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries2.types index a854c159e0c..e67ff2f8de6 100644 --- a/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries2.types +++ b/tests/baselines/reference/overloadBindingAcrossDeclarationBoundaries2.types @@ -108,17 +108,17 @@ var a1 = a.a({}); >a.a : { (o: Opt1): Opt1; (o: Opt2): Opt2; (o: Opt3): Opt3; (o: Opt4): Opt4; } >a : A >a : { (o: Opt1): Opt1; (o: Opt2): Opt2; (o: Opt3): Opt3; (o: Opt4): Opt4; } ->{} : { r?: any; } +>{} : {} var a1 = a({}); >a1 : Opt3 >a({}) : Opt3 >a : A ->{} : { r?: any; } +>{} : {} var a1 = new a({}); >a1 : Opt3 >new a({}) : Opt3 >a : A ->{} : { r?: any; } +>{} : {} diff --git a/tests/baselines/reference/typeAnnotationBestCommonTypeInArrayLiteral.types b/tests/baselines/reference/typeAnnotationBestCommonTypeInArrayLiteral.types index 661aa3c3cbb..27fcd05bb28 100644 --- a/tests/baselines/reference/typeAnnotationBestCommonTypeInArrayLiteral.types +++ b/tests/baselines/reference/typeAnnotationBestCommonTypeInArrayLiteral.types @@ -23,16 +23,16 @@ interface IMenuItem { var menuData: IMenuItem[] = [ >menuData : IMenuItem[] >IMenuItem : IMenuItem ->[ { "id": "ourLogo", "type": "image", "link": "", "icon": "modules/menu/logo.svg" }, { "id": "productName", "type": "default", "link": "", "text": "Product Name" }] : ({ "id": string; "type": string; "link": string; "icon": string; classes?: string; text?: string; } | { "id": string; "type": string; "link": string; "text": string; classes?: string; icon?: string; })[] +>[ { "id": "ourLogo", "type": "image", "link": "", "icon": "modules/menu/logo.svg" }, { "id": "productName", "type": "default", "link": "", "text": "Product Name" }] : ({ "id": string; "type": string; "link": string; "icon": string; } | { "id": string; "type": string; "link": string; "text": string; })[] { ->{ "id": "ourLogo", "type": "image", "link": "", "icon": "modules/menu/logo.svg" } : { "id": string; "type": string; "link": string; "icon": string; classes?: string; text?: string; } +>{ "id": "ourLogo", "type": "image", "link": "", "icon": "modules/menu/logo.svg" } : { "id": string; "type": string; "link": string; "icon": string; } "id": "ourLogo", "type": "image", "link": "", "icon": "modules/menu/logo.svg" }, { ->{ "id": "productName", "type": "default", "link": "", "text": "Product Name" } : { "id": string; "type": string; "link": string; "text": string; classes?: string; icon?: string; } +>{ "id": "productName", "type": "default", "link": "", "text": "Product Name" } : { "id": string; "type": string; "link": string; "text": string; } "id": "productName", "type": "default", diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 9e4f5ea1d1b..a3347457b8a 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -1317,11 +1317,11 @@ compiled2({ epithet: "stooge" }); >epithet : string _.templateSettings = { ->_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g} : { interpolate: RegExp; evaluate?: RegExp; escape?: RegExp; } +>_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g} : { interpolate: RegExp; } >_.templateSettings : Underscore.TemplateSettings >_ : Underscore.Static >templateSettings : Underscore.TemplateSettings ->{ interpolate: /\{\{(.+?)\}\}/g} : { interpolate: RegExp; evaluate?: RegExp; escape?: RegExp; } +>{ interpolate: /\{\{(.+?)\}\}/g} : { interpolate: RegExp; } interpolate: /\{\{(.+?)\}\}/g >interpolate : RegExp @@ -1347,7 +1347,7 @@ _.template("Using 'with': <%= data.answer %>", { answer: 'no' }, { variable: 'da >template : { (templateString: string): (data: any) => string; (templateString: string, data: any, settings?: Underscore.TemplateSettings): string; } >{ answer: 'no' } : { answer: string; } >answer : string ->{ variable: 'data' } : { variable: string; evaluate?: RegExp; interpolate?: RegExp; escape?: RegExp; } +>{ variable: 'data' } : { variable: string; } >variable : string === tests/cases/compiler/underscoreTest1_underscore.ts === From a298835f01b660e7b44ea526fde8060fa03779bb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 26 Jan 2015 16:23:21 -0800 Subject: [PATCH 3/3] Addressing CR feedback --- src/compiler/checker.ts | 15 +++++++++------ src/compiler/types.ts | 42 ++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 431d81696a1..9e88a6cb01a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -66,8 +66,8 @@ module ts { var numberType = createIntrinsicType(TypeFlags.Number, "number"); var booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean"); var voidType = createIntrinsicType(TypeFlags.Void, "void"); - var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefined, "undefined"); - var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefined, "null"); + var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined"); + var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null"); var unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); var resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__"); @@ -2807,6 +2807,9 @@ module ts { } } + // This function is used to propagate widening flags when creating new object types references and union types. + // It is only necessary to do so if a constituent type might be the undefined type, the null type, or the type + // of an object literal (since those types have widening related information we need to track). function getWideningFlagsOfTypes(types: Type[]): TypeFlags { var result: TypeFlags = 0; for (var i = 0; i < types.length; i++) { @@ -4111,7 +4114,7 @@ module ts { var symbol = createSymbol(p.flags | SymbolFlags.Transient, p.name); symbol.declarations = p.declarations; symbol.parent = p.parent; - symbol.type = getWidenedType(getTypeOfSymbol(p)); + symbol.type = widenedType; symbol.target = p; if (p.valueDeclaration) symbol.valueDeclaration = p.valueDeclaration; p = symbol; @@ -4160,7 +4163,7 @@ module ts { var errorReported = false; forEach(getPropertiesOfObjectType(type), p => { var t = getTypeOfSymbol(p); - if (t.flags & TypeFlags.ContainsUndefined) { + if (t.flags & TypeFlags.ContainsUndefinedOrNull) { if (!reportWideningErrorsInType(t)) { error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t))); } @@ -4204,7 +4207,7 @@ module ts { } function reportErrorsFromWidening(declaration: Declaration, type: Type) { - if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefined) { + if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefinedOrNull) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAnyError(declaration, type); @@ -5464,7 +5467,7 @@ module ts { var stringIndexType = getIndexType(IndexKind.String); var numberIndexType = getIndexType(IndexKind.Number); var result = createAnonymousType(node.symbol, properties, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsLiteral | (typeFlags & TypeFlags.ContainsUndefined); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull); return result; function getIndexType(kind: IndexKind) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 474fdf30fed..ad20efcef3e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1266,32 +1266,32 @@ module ts { } export const enum TypeFlags { - Any = 0x00000001, - String = 0x00000002, - Number = 0x00000004, - Boolean = 0x00000008, - Void = 0x00000010, - Undefined = 0x00000020, - Null = 0x00000040, - Enum = 0x00000080, // Enum type - StringLiteral = 0x00000100, // String literal type - TypeParameter = 0x00000200, // Type parameter - Class = 0x00000400, // Class - Interface = 0x00000800, // Interface - Reference = 0x00001000, // Generic type reference - Tuple = 0x00002000, // Tuple - Union = 0x00004000, // Union - Anonymous = 0x00008000, // Anonymous - FromSignature = 0x00010000, // Created for signature assignment check - ObjectLiteral = 0x00020000, // Originates in an object literal - ContainsUndefined = 0x00040000, // Type is or contains Undefined or Null type - ContainsLiteral = 0x00080000, // Type is or contains object literal type + Any = 0x00000001, + String = 0x00000002, + Number = 0x00000004, + Boolean = 0x00000008, + Void = 0x00000010, + Undefined = 0x00000020, + Null = 0x00000040, + Enum = 0x00000080, // Enum type + StringLiteral = 0x00000100, // String literal type + TypeParameter = 0x00000200, // Type parameter + Class = 0x00000400, // Class + Interface = 0x00000800, // Interface + Reference = 0x00001000, // Generic type reference + Tuple = 0x00002000, // Tuple + Union = 0x00004000, // Union + Anonymous = 0x00008000, // Anonymous + FromSignature = 0x00010000, // Created for signature assignment check + ObjectLiteral = 0x00020000, // Originates in an object literal + ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type + ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null, StringLike = String | StringLiteral, NumberLike = Number | Enum, ObjectType = Class | Interface | Reference | Tuple | Anonymous, - RequiresWidening = ContainsUndefined | ContainsLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral } // Properties common to all types