mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Merge pull request #1795 from Microsoft/objectLiteralWidening
Improved subtype compatibility rules for types of object literals
This commit is contained in:
commit
ba5a61293c
@ -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.ContainsUndefinedOrNull, "undefined");
|
||||
var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null");
|
||||
var unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
|
||||
var resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__");
|
||||
|
||||
@ -2826,15 +2826,22 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getUnwidenedFlagOfTypes(types: Type[]): TypeFlags {
|
||||
return forEach(types, t => t.flags & TypeFlags.Unwidened) || 0;
|
||||
// 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++) {
|
||||
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] = <TypeReference>createObjectType(flags, target.symbol);
|
||||
type.target = target;
|
||||
type.typeArguments = typeArguments;
|
||||
@ -3095,7 +3102,7 @@ module ts {
|
||||
var id = getTypeListId(sortedTypes);
|
||||
var type = unionTypes[id];
|
||||
if (!type) {
|
||||
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | getUnwidenedFlagOfTypes(sortedTypes));
|
||||
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(sortedTypes));
|
||||
type.types = sortedTypes;
|
||||
}
|
||||
return type;
|
||||
@ -3711,12 +3718,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));
|
||||
}
|
||||
@ -4107,10 +4115,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 && (<TypeReference>type).target === globalArrayType;
|
||||
}
|
||||
@ -4123,13 +4127,18 @@ module ts {
|
||||
var properties = getPropertiesOfObjectType(type);
|
||||
var members: SymbolTable = {};
|
||||
forEach(properties, p => {
|
||||
var symbol = <TransientSymbol>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 = <TransientSymbol>createSymbol(p.flags | SymbolFlags.Transient, p.name);
|
||||
symbol.declarations = p.declarations;
|
||||
symbol.parent = p.parent;
|
||||
symbol.type = widenedType;
|
||||
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);
|
||||
@ -4139,16 +4148,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((<UnionType>type).types, getWidenedType));
|
||||
}
|
||||
if (isTypeOfObjectLiteral(type)) {
|
||||
return getWidenedTypeOfObjectLiteral(type);
|
||||
}
|
||||
if (isArrayType(type)) {
|
||||
return createArrayType(getWidenedType((<TypeReference>type).typeArguments[0]));
|
||||
}
|
||||
@ -4169,11 +4178,11 @@ module ts {
|
||||
if (isArrayType(type)) {
|
||||
return reportWideningErrorsInType((<TypeReference>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.ContainsUndefinedOrNull) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t)));
|
||||
}
|
||||
@ -4217,7 +4226,7 @@ module ts {
|
||||
}
|
||||
|
||||
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
|
||||
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.Unwidened) {
|
||||
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);
|
||||
@ -5492,21 +5501,10 @@ module ts {
|
||||
propertiesArray.push(member);
|
||||
}
|
||||
|
||||
// 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(propertiesTable, p.name)) {
|
||||
propertiesTable[p.name] = p;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var stringIndexType = getIndexType(IndexKind.String);
|
||||
var numberIndexType = getIndexType(IndexKind.Number);
|
||||
var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
|
||||
result.flags |= (typeFlags & TypeFlags.Unwidened);
|
||||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
|
||||
return result;
|
||||
|
||||
function getIndexType(kind: IndexKind) {
|
||||
@ -5525,7 +5523,9 @@ module ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
return propTypes.length ? getUnionType(propTypes) : undefinedType;
|
||||
var result = propTypes.length ? getUnionType(propTypes) : undefinedType;
|
||||
typeFlags |= result.flags;
|
||||
return result;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -1266,29 +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
|
||||
Unwidened = 0x00020000, // Unwidened type (is or contains Undefined or Null 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 = ContainsUndefinedOrNull | ContainsObjectLiteral
|
||||
}
|
||||
|
||||
// Properties common to all types
|
||||
|
||||
@ -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" }, {}];
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ 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<number>
|
||||
>interfaceWithOptional : interfaceWithOptional<T>
|
||||
>{ } : { one?: number; }
|
||||
>{ } : {}
|
||||
|
||||
export var __val__obj3 = obj3;
|
||||
>__val__obj3 : interfaceWithOptional<number>
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ 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<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -12,7 +12,7 @@ module __test1__ {
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; two?: string; }
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
|
||||
@ -14,8 +14,8 @@ Object.defineProperty({}, "0", <PropertyDescriptor>({
|
||||
>{} : {}
|
||||
><PropertyDescriptor>({ 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
|
||||
|
||||
@ -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 = <IDirectChildrenMap>{};
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! 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'.
|
||||
21
tests/baselines/reference/indexer2.types
Normal file
21
tests/baselines/reference/indexer2.types
Normal file
@ -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 = <IDirectChildrenMap>{};
|
||||
>directChildrenMap : IDirectChildrenMap
|
||||
><IDirectChildrenMap>{} : IDirectChildrenMap
|
||||
>IDirectChildrenMap : IDirectChildrenMap
|
||||
>{} : { [x: number]: undefined; }
|
||||
|
||||
@ -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 = <IDirectChildrenMap>{};
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! 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'.
|
||||
var directChildrenMap = <IDirectChildrenMap>{};
|
||||
@ -41,8 +41,8 @@ tests/cases/compiler/intTypeCheck.ts(148,5): error TS2322: Type 'boolean' is not
|
||||
tests/cases/compiler/intTypeCheck.ts(148,21): error TS1109: Expression expected.
|
||||
tests/cases/compiler/intTypeCheck.ts(148,22): error TS2304: Cannot find name 'i4'.
|
||||
tests/cases/compiler/intTypeCheck.ts(149,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
|
||||
tests/cases/compiler/intTypeCheck.ts(154,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(154,5): error TS2322: Type '{}' is not assignable to type 'i5'.
|
||||
Property 'p' is missing in type '{}'.
|
||||
tests/cases/compiler/intTypeCheck.ts(155,5): error TS2322: Type 'Object' is not assignable to type 'i5'.
|
||||
Property 'p' is missing in type 'Object'.
|
||||
tests/cases/compiler/intTypeCheck.ts(156,17): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
|
||||
@ -321,8 +321,8 @@ tests/cases/compiler/intTypeCheck.ts(205,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'.
|
||||
|
||||
@ -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
|
||||
|
||||
};
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
>obj : {}
|
||||
><PropertyDescriptor>({ 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
|
||||
|
||||
@ -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 : <T>(param: { x?: T; }) => T
|
||||
>{} : { x?: {}; }
|
||||
>{} : {}
|
||||
|
||||
var b: {};
|
||||
>b : {}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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; }
|
||||
>{} : {}
|
||||
|
||||
|
||||
@ -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; }
|
||||
>{} : {}
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 ===
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user