From efd9f60d146630eed652a37ac065bf343808719b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 19 Jan 2015 10:48:01 -0800 Subject: [PATCH 1/4] Allow union types in indexing expressions. --- src/compiler/checker.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ad62c1d639f0..0f8820c0610a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -91,6 +91,7 @@ module ts { var globalTemplateStringsArrayType: ObjectType; var anyArrayType: Type; + var stringOrNumberType: Type; var tupleTypes: Map = {}; var unionTypes: Map = {}; @@ -5650,10 +5651,10 @@ module ts { } // Check for compatible indexer types. - if (indexType.flags & (TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) { + if (indexType.flags & (TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, stringOrNumberType)) { // Try to use a number indexer. - if (indexType.flags & (TypeFlags.Any | TypeFlags.NumberLike)) { + if (indexType.flags & (TypeFlags.Any | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, numberType)) { var numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number); if (numberIndexType) { return numberIndexType; @@ -10059,6 +10060,7 @@ module ts { ? getGlobalType("TemplateStringsArray") : unknownType; anyArrayType = createArrayType(anyType); + stringOrNumberType = getUnionType([stringType, numberType]); } From 857385030841f017881e45b0a1bfbbb68560fae7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 21 Jan 2015 13:54:05 -0800 Subject: [PATCH 2/4] Consistent handling of string-like and number-like values in expressions --- src/compiler/checker.ts | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f279dea186a7a..708b6eaa696f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5621,7 +5621,7 @@ module ts { } var isConstEnum = isConstEnumObjectType(objectType); - if (isConstEnum && + if (isConstEnum && (!node.argumentExpression || node.argumentExpression.kind !== SyntaxKind.StringLiteral)) { error(node.argumentExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); return unknownType; @@ -5653,10 +5653,10 @@ module ts { } // Check for compatible indexer types. - if (indexType.flags & (TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, stringOrNumberType)) { + if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) { // Try to use a number indexer. - if (indexType.flags & (TypeFlags.Any | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, numberType)) { + if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) { var numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number); if (numberIndexType) { return numberIndexType; @@ -6557,7 +6557,7 @@ module ts { } function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean { - if (!(type.flags & (TypeFlags.Any | TypeFlags.NumberLike))) { + if (!isTypeOfKind(type, TypeFlags.Any | TypeFlags.NumberLike)) { error(operand, diagnostic); return false; } @@ -6708,12 +6708,21 @@ module ts { return numberType; } - // Return true if type an object type, a type parameter, or a union type composed of only those kinds of types - function isStructuredType(type: Type): boolean { + // Return true if type has the given flags, or is a union type composed of types that all have those flags + function isTypeOfKind(type: Type, kind: TypeFlags): boolean { + if (type.flags & kind) { + return true; + } if (type.flags & TypeFlags.Union) { - return !forEach((type).types, t => !isStructuredType(t)); + var types = (type).types; + for (var i = 0; i < types.length; i++) { + if (!(types[i].flags & kind)) { + return false; + } + } + return true; } - return (type.flags & (TypeFlags.ObjectType | TypeFlags.TypeParameter)) !== 0; + return false; } function isConstEnumObjectType(type: Type): boolean { @@ -6730,7 +6739,7 @@ module ts { // and the right operand to be of type Any or a subtype of the 'Function' interface type. // The result is always of the Boolean primitive type. // NOTE: do not raise error if leftType is unknown as related error was already reported - if (!(leftType.flags & TypeFlags.Any || isStructuredType(leftType))) { + if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) { error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } // NOTE: do not raise error if right is unknown as related error was already reported @@ -6745,10 +6754,10 @@ module ts { // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. // The result is always of the Boolean primitive type. - if (leftType !== anyType && leftType !== stringType && leftType !== numberType) { + if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) { error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number); } - if (!(rightType.flags & TypeFlags.Any || isStructuredType(rightType))) { + if (!isTypeOfKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) { error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; @@ -6909,16 +6918,16 @@ module ts { if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType; var resultType: Type; - if (leftType.flags & TypeFlags.NumberLike && rightType.flags & TypeFlags.NumberLike) { + if (isTypeOfKind(leftType, TypeFlags.NumberLike) && isTypeOfKind(rightType, TypeFlags.NumberLike)) { // Operands of an enum type are treated as having the primitive type Number. // If both operands are of the Number primitive type, the result is of the Number primitive type. resultType = numberType; } - else if (leftType.flags & TypeFlags.StringLike || rightType.flags & TypeFlags.StringLike) { + else if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) { // If one or both operands are of the String primitive type, the result is of the String primitive type. resultType = stringType; } - else if (leftType.flags & TypeFlags.Any || leftType === unknownType || rightType.flags & TypeFlags.Any || rightType === unknownType) { + else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) { // Otherwise, the result is of type Any. // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. resultType = anyType; @@ -8274,7 +8283,7 @@ module ts { var exprType = checkExpression(node.expression); // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!(exprType.flags & TypeFlags.Any || isStructuredType(exprType))) { + if (!isTypeOfKind(exprType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) { error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } From f34620db6320fee0a14c478bc4a1ec70526a324a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 21 Jan 2015 13:55:07 -0800 Subject: [PATCH 3/4] Modifying and adding tests --- .../additionOperatorWithNumberAndEnum.js | 24 +- .../additionOperatorWithNumberAndEnum.types | 48 + .../arithmeticOperatorWithEnumUnion.js | 301 ++++++ .../arithmeticOperatorWithEnumUnion.types | 903 ++++++++++++++++++ .../inOperatorWithInvalidOperands.errors.txt | 8 +- .../reference/propertyAccess.errors.txt | 76 +- tests/baselines/reference/propertyAccess.js | 68 +- .../additionOperatorWithNumberAndEnum.ts | 11 +- .../arithmeticOperatorWithEnumUnion.ts | 154 +++ .../propertyAccess/propertyAccess.ts | 35 +- 10 files changed, 1560 insertions(+), 68 deletions(-) create mode 100644 tests/baselines/reference/arithmeticOperatorWithEnumUnion.js create mode 100644 tests/baselines/reference/arithmeticOperatorWithEnumUnion.types create mode 100644 tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithEnumUnion.ts diff --git a/tests/baselines/reference/additionOperatorWithNumberAndEnum.js b/tests/baselines/reference/additionOperatorWithNumberAndEnum.js index 05bca7a4c0cd5..231831518e6c7 100644 --- a/tests/baselines/reference/additionOperatorWithNumberAndEnum.js +++ b/tests/baselines/reference/additionOperatorWithNumberAndEnum.js @@ -1,8 +1,10 @@ //// [additionOperatorWithNumberAndEnum.ts] enum E { a, b } +enum F { c, d } var a: number; var b: E; +var c: E | F; var r1 = a + a; var r2 = a + b; @@ -12,7 +14,15 @@ var r4 = b + b; var r5 = 0 + a; var r6 = E.a + 0; var r7 = E.a + E.b; -var r8 = E['a'] + E['b']; +var r8 = E['a'] + E['b']; +var r9 = E['a'] + F['c']; + +var r10 = a + c; +var r11 = c + a; +var r12 = b + c; +var r13 = c + b; +var r14 = c + c; + //// [additionOperatorWithNumberAndEnum.js] var E; @@ -20,8 +30,14 @@ var E; E[E["a"] = 0] = "a"; E[E["b"] = 1] = "b"; })(E || (E = {})); +var F; +(function (F) { + F[F["c"] = 0] = "c"; + F[F["d"] = 1] = "d"; +})(F || (F = {})); var a; var b; +var c; var r1 = a + a; var r2 = a + b; var r3 = b + a; @@ -30,3 +46,9 @@ var r5 = 0 + a; var r6 = 0 /* a */ + 0; var r7 = 0 /* a */ + 1 /* b */; var r8 = 0 /* 'a' */ + 1 /* 'b' */; +var r9 = 0 /* 'a' */ + 0 /* 'c' */; +var r10 = a + c; +var r11 = c + a; +var r12 = b + c; +var r13 = c + b; +var r14 = c + c; diff --git a/tests/baselines/reference/additionOperatorWithNumberAndEnum.types b/tests/baselines/reference/additionOperatorWithNumberAndEnum.types index 268f74b69ffc6..c22939ffd982d 100644 --- a/tests/baselines/reference/additionOperatorWithNumberAndEnum.types +++ b/tests/baselines/reference/additionOperatorWithNumberAndEnum.types @@ -4,6 +4,11 @@ enum E { a, b } >a : E >b : E +enum F { c, d } +>F : F +>c : F +>d : F + var a: number; >a : number @@ -11,6 +16,11 @@ var b: E; >b : E >E : E +var c: E | F; +>c : E | F +>E : E +>F : F + var r1 = a + a; >r1 : number >a + a : number @@ -65,3 +75,41 @@ var r8 = E['a'] + E['b']; >E['b'] : E >E : typeof E +var r9 = E['a'] + F['c']; +>r9 : number +>E['a'] + F['c'] : number +>E['a'] : E +>E : typeof E +>F['c'] : F +>F : typeof F + +var r10 = a + c; +>r10 : number +>a + c : number +>a : number +>c : E | F + +var r11 = c + a; +>r11 : number +>c + a : number +>c : E | F +>a : number + +var r12 = b + c; +>r12 : number +>b + c : number +>b : E +>c : E | F + +var r13 = c + b; +>r13 : number +>c + b : number +>c : E | F +>b : E + +var r14 = c + c; +>r14 : number +>c + c : number +>c : E | F +>c : E | F + diff --git a/tests/baselines/reference/arithmeticOperatorWithEnumUnion.js b/tests/baselines/reference/arithmeticOperatorWithEnumUnion.js new file mode 100644 index 0000000000000..315f7dd237b7f --- /dev/null +++ b/tests/baselines/reference/arithmeticOperatorWithEnumUnion.js @@ -0,0 +1,301 @@ +//// [arithmeticOperatorWithEnumUnion.ts] +// operands of an enum type are treated as having the primitive type Number. + +enum E { + a, + b +} +enum F { + c, + d +} + +var a: any; +var b: number; +var c: E | F; + +// operator * +var ra1 = c * a; +var ra2 = c * b; +var ra3 = c * c; +var ra4 = a * c; +var ra5 = b * c; +var ra6 = E.a * a; +var ra7 = E.a * b; +var ra8 = E.a * E.b; +var ra9 = E.a * 1; +var ra10 = a * E.b; +var ra11 = b * E.b; +var ra12 = 1 * E.b; + +// operator / +var rb1 = c / a; +var rb2 = c / b; +var rb3 = c / c; +var rb4 = a / c; +var rb5 = b / c; +var rb6 = E.a / a; +var rb7 = E.a / b; +var rb8 = E.a / E.b; +var rb9 = E.a / 1; +var rb10 = a / E.b; +var rb11 = b / E.b; +var rb12 = 1 / E.b; + +// operator % +var rc1 = c % a; +var rc2 = c % b; +var rc3 = c % c; +var rc4 = a % c; +var rc5 = b % c; +var rc6 = E.a % a; +var rc7 = E.a % b; +var rc8 = E.a % E.b; +var rc9 = E.a % 1; +var rc10 = a % E.b; +var rc11 = b % E.b; +var rc12 = 1 % E.b; + +// operator - +var rd1 = c - a; +var rd2 = c - b; +var rd3 = c - c; +var rd4 = a - c; +var rd5 = b - c; +var rd6 = E.a - a; +var rd7 = E.a - b; +var rd8 = E.a - E.b; +var rd9 = E.a - 1; +var rd10 = a - E.b; +var rd11 = b - E.b; +var rd12 = 1 - E.b; + +// operator << +var re1 = c << a; +var re2 = c << b; +var re3 = c << c; +var re4 = a << c; +var re5 = b << c; +var re6 = E.a << a; +var re7 = E.a << b; +var re8 = E.a << E.b; +var re9 = E.a << 1; +var re10 = a << E.b; +var re11 = b << E.b; +var re12 = 1 << E.b; + +// operator >> +var rf1 = c >> a; +var rf2 = c >> b; +var rf3 = c >> c; +var rf4 = a >> c; +var rf5 = b >> c; +var rf6 = E.a >> a; +var rf7 = E.a >> b; +var rf8 = E.a >> E.b; +var rf9 = E.a >> 1; +var rf10 = a >> E.b; +var rf11 = b >> E.b; +var rf12 = 1 >> E.b; + +// operator >>> +var rg1 = c >>> a; +var rg2 = c >>> b; +var rg3 = c >>> c; +var rg4 = a >>> c; +var rg5 = b >>> c; +var rg6 = E.a >>> a; +var rg7 = E.a >>> b; +var rg8 = E.a >>> E.b; +var rg9 = E.a >>> 1; +var rg10 = a >>> E.b; +var rg11 = b >>> E.b; +var rg12 = 1 >>> E.b; + +// operator & +var rh1 = c & a; +var rh2 = c & b; +var rh3 = c & c; +var rh4 = a & c; +var rh5 = b & c; +var rh6 = E.a & a; +var rh7 = E.a & b; +var rh8 = E.a & E.b; +var rh9 = E.a & 1; +var rh10 = a & E.b; +var rh11 = b & E.b; +var rh12 = 1 & E.b; + +// operator ^ +var ri1 = c ^ a; +var ri2 = c ^ b; +var ri3 = c ^ c; +var ri4 = a ^ c; +var ri5 = b ^ c; +var ri6 = E.a ^ a; +var ri7 = E.a ^ b; +var ri8 = E.a ^ E.b; +var ri9 = E.a ^ 1; +var ri10 = a ^ E.b; +var ri11 = b ^ E.b; +var ri12 = 1 ^ E.b; + +// operator | +var rj1 = c | a; +var rj2 = c | b; +var rj3 = c | c; +var rj4 = a | c; +var rj5 = b | c; +var rj6 = E.a | a; +var rj7 = E.a | b; +var rj8 = E.a | E.b; +var rj9 = E.a | 1; +var rj10 = a | E.b; +var rj11 = b | E.b; +var rj12 = 1 | E.b; + +//// [arithmeticOperatorWithEnumUnion.js] +// operands of an enum type are treated as having the primitive type Number. +var E; +(function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; +})(E || (E = {})); +var F; +(function (F) { + F[F["c"] = 0] = "c"; + F[F["d"] = 1] = "d"; +})(F || (F = {})); +var a; +var b; +var c; +// operator * +var ra1 = c * a; +var ra2 = c * b; +var ra3 = c * c; +var ra4 = a * c; +var ra5 = b * c; +var ra6 = 0 /* a */ * a; +var ra7 = 0 /* a */ * b; +var ra8 = 0 /* a */ * 1 /* b */; +var ra9 = 0 /* a */ * 1; +var ra10 = a * 1 /* b */; +var ra11 = b * 1 /* b */; +var ra12 = 1 * 1 /* b */; +// operator / +var rb1 = c / a; +var rb2 = c / b; +var rb3 = c / c; +var rb4 = a / c; +var rb5 = b / c; +var rb6 = 0 /* a */ / a; +var rb7 = 0 /* a */ / b; +var rb8 = 0 /* a */ / 1 /* b */; +var rb9 = 0 /* a */ / 1; +var rb10 = a / 1 /* b */; +var rb11 = b / 1 /* b */; +var rb12 = 1 / 1 /* b */; +// operator % +var rc1 = c % a; +var rc2 = c % b; +var rc3 = c % c; +var rc4 = a % c; +var rc5 = b % c; +var rc6 = 0 /* a */ % a; +var rc7 = 0 /* a */ % b; +var rc8 = 0 /* a */ % 1 /* b */; +var rc9 = 0 /* a */ % 1; +var rc10 = a % 1 /* b */; +var rc11 = b % 1 /* b */; +var rc12 = 1 % 1 /* b */; +// operator - +var rd1 = c - a; +var rd2 = c - b; +var rd3 = c - c; +var rd4 = a - c; +var rd5 = b - c; +var rd6 = 0 /* a */ - a; +var rd7 = 0 /* a */ - b; +var rd8 = 0 /* a */ - 1 /* b */; +var rd9 = 0 /* a */ - 1; +var rd10 = a - 1 /* b */; +var rd11 = b - 1 /* b */; +var rd12 = 1 - 1 /* b */; +// operator << +var re1 = c << a; +var re2 = c << b; +var re3 = c << c; +var re4 = a << c; +var re5 = b << c; +var re6 = 0 /* a */ << a; +var re7 = 0 /* a */ << b; +var re8 = 0 /* a */ << 1 /* b */; +var re9 = 0 /* a */ << 1; +var re10 = a << 1 /* b */; +var re11 = b << 1 /* b */; +var re12 = 1 << 1 /* b */; +// operator >> +var rf1 = c >> a; +var rf2 = c >> b; +var rf3 = c >> c; +var rf4 = a >> c; +var rf5 = b >> c; +var rf6 = 0 /* a */ >> a; +var rf7 = 0 /* a */ >> b; +var rf8 = 0 /* a */ >> 1 /* b */; +var rf9 = 0 /* a */ >> 1; +var rf10 = a >> 1 /* b */; +var rf11 = b >> 1 /* b */; +var rf12 = 1 >> 1 /* b */; +// operator >>> +var rg1 = c >>> a; +var rg2 = c >>> b; +var rg3 = c >>> c; +var rg4 = a >>> c; +var rg5 = b >>> c; +var rg6 = 0 /* a */ >>> a; +var rg7 = 0 /* a */ >>> b; +var rg8 = 0 /* a */ >>> 1 /* b */; +var rg9 = 0 /* a */ >>> 1; +var rg10 = a >>> 1 /* b */; +var rg11 = b >>> 1 /* b */; +var rg12 = 1 >>> 1 /* b */; +// operator & +var rh1 = c & a; +var rh2 = c & b; +var rh3 = c & c; +var rh4 = a & c; +var rh5 = b & c; +var rh6 = 0 /* a */ & a; +var rh7 = 0 /* a */ & b; +var rh8 = 0 /* a */ & 1 /* b */; +var rh9 = 0 /* a */ & 1; +var rh10 = a & 1 /* b */; +var rh11 = b & 1 /* b */; +var rh12 = 1 & 1 /* b */; +// operator ^ +var ri1 = c ^ a; +var ri2 = c ^ b; +var ri3 = c ^ c; +var ri4 = a ^ c; +var ri5 = b ^ c; +var ri6 = 0 /* a */ ^ a; +var ri7 = 0 /* a */ ^ b; +var ri8 = 0 /* a */ ^ 1 /* b */; +var ri9 = 0 /* a */ ^ 1; +var ri10 = a ^ 1 /* b */; +var ri11 = b ^ 1 /* b */; +var ri12 = 1 ^ 1 /* b */; +// operator | +var rj1 = c | a; +var rj2 = c | b; +var rj3 = c | c; +var rj4 = a | c; +var rj5 = b | c; +var rj6 = 0 /* a */ | a; +var rj7 = 0 /* a */ | b; +var rj8 = 0 /* a */ | 1 /* b */; +var rj9 = 0 /* a */ | 1; +var rj10 = a | 1 /* b */; +var rj11 = b | 1 /* b */; +var rj12 = 1 | 1 /* b */; diff --git a/tests/baselines/reference/arithmeticOperatorWithEnumUnion.types b/tests/baselines/reference/arithmeticOperatorWithEnumUnion.types new file mode 100644 index 0000000000000..7b65ddf7f00c2 --- /dev/null +++ b/tests/baselines/reference/arithmeticOperatorWithEnumUnion.types @@ -0,0 +1,903 @@ +=== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithEnumUnion.ts === +// operands of an enum type are treated as having the primitive type Number. + +enum E { +>E : E + + a, +>a : E + + b +>b : E +} +enum F { +>F : F + + c, +>c : F + + d +>d : F +} + +var a: any; +>a : any + +var b: number; +>b : number + +var c: E | F; +>c : E | F +>E : E +>F : F + +// operator * +var ra1 = c * a; +>ra1 : number +>c * a : number +>c : E | F +>a : any + +var ra2 = c * b; +>ra2 : number +>c * b : number +>c : E | F +>b : number + +var ra3 = c * c; +>ra3 : number +>c * c : number +>c : E | F +>c : E | F + +var ra4 = a * c; +>ra4 : number +>a * c : number +>a : any +>c : E | F + +var ra5 = b * c; +>ra5 : number +>b * c : number +>b : number +>c : E | F + +var ra6 = E.a * a; +>ra6 : number +>E.a * a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var ra7 = E.a * b; +>ra7 : number +>E.a * b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var ra8 = E.a * E.b; +>ra8 : number +>E.a * E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var ra9 = E.a * 1; +>ra9 : number +>E.a * 1 : number +>E.a : E +>E : typeof E +>a : E + +var ra10 = a * E.b; +>ra10 : number +>a * E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var ra11 = b * E.b; +>ra11 : number +>b * E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var ra12 = 1 * E.b; +>ra12 : number +>1 * E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator / +var rb1 = c / a; +>rb1 : number +>c / a : number +>c : E | F +>a : any + +var rb2 = c / b; +>rb2 : number +>c / b : number +>c : E | F +>b : number + +var rb3 = c / c; +>rb3 : number +>c / c : number +>c : E | F +>c : E | F + +var rb4 = a / c; +>rb4 : number +>a / c : number +>a : any +>c : E | F + +var rb5 = b / c; +>rb5 : number +>b / c : number +>b : number +>c : E | F + +var rb6 = E.a / a; +>rb6 : number +>E.a / a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rb7 = E.a / b; +>rb7 : number +>E.a / b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rb8 = E.a / E.b; +>rb8 : number +>E.a / E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rb9 = E.a / 1; +>rb9 : number +>E.a / 1 : number +>E.a : E +>E : typeof E +>a : E + +var rb10 = a / E.b; +>rb10 : number +>a / E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rb11 = b / E.b; +>rb11 : number +>b / E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rb12 = 1 / E.b; +>rb12 : number +>1 / E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator % +var rc1 = c % a; +>rc1 : number +>c % a : number +>c : E | F +>a : any + +var rc2 = c % b; +>rc2 : number +>c % b : number +>c : E | F +>b : number + +var rc3 = c % c; +>rc3 : number +>c % c : number +>c : E | F +>c : E | F + +var rc4 = a % c; +>rc4 : number +>a % c : number +>a : any +>c : E | F + +var rc5 = b % c; +>rc5 : number +>b % c : number +>b : number +>c : E | F + +var rc6 = E.a % a; +>rc6 : number +>E.a % a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rc7 = E.a % b; +>rc7 : number +>E.a % b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rc8 = E.a % E.b; +>rc8 : number +>E.a % E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rc9 = E.a % 1; +>rc9 : number +>E.a % 1 : number +>E.a : E +>E : typeof E +>a : E + +var rc10 = a % E.b; +>rc10 : number +>a % E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rc11 = b % E.b; +>rc11 : number +>b % E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rc12 = 1 % E.b; +>rc12 : number +>1 % E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator - +var rd1 = c - a; +>rd1 : number +>c - a : number +>c : E | F +>a : any + +var rd2 = c - b; +>rd2 : number +>c - b : number +>c : E | F +>b : number + +var rd3 = c - c; +>rd3 : number +>c - c : number +>c : E | F +>c : E | F + +var rd4 = a - c; +>rd4 : number +>a - c : number +>a : any +>c : E | F + +var rd5 = b - c; +>rd5 : number +>b - c : number +>b : number +>c : E | F + +var rd6 = E.a - a; +>rd6 : number +>E.a - a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rd7 = E.a - b; +>rd7 : number +>E.a - b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rd8 = E.a - E.b; +>rd8 : number +>E.a - E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rd9 = E.a - 1; +>rd9 : number +>E.a - 1 : number +>E.a : E +>E : typeof E +>a : E + +var rd10 = a - E.b; +>rd10 : number +>a - E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rd11 = b - E.b; +>rd11 : number +>b - E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rd12 = 1 - E.b; +>rd12 : number +>1 - E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator << +var re1 = c << a; +>re1 : number +>c << a : number +>c : E | F +>a : any + +var re2 = c << b; +>re2 : number +>c << b : number +>c : E | F +>b : number + +var re3 = c << c; +>re3 : number +>c << c : number +>c : E | F +>c : E | F + +var re4 = a << c; +>re4 : number +>a << c : number +>a : any +>c : E | F + +var re5 = b << c; +>re5 : number +>b << c : number +>b : number +>c : E | F + +var re6 = E.a << a; +>re6 : number +>E.a << a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var re7 = E.a << b; +>re7 : number +>E.a << b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var re8 = E.a << E.b; +>re8 : number +>E.a << E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var re9 = E.a << 1; +>re9 : number +>E.a << 1 : number +>E.a : E +>E : typeof E +>a : E + +var re10 = a << E.b; +>re10 : number +>a << E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var re11 = b << E.b; +>re11 : number +>b << E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var re12 = 1 << E.b; +>re12 : number +>1 << E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator >> +var rf1 = c >> a; +>rf1 : number +>c >> a : number +>c : E | F +>a : any + +var rf2 = c >> b; +>rf2 : number +>c >> b : number +>c : E | F +>b : number + +var rf3 = c >> c; +>rf3 : number +>c >> c : number +>c : E | F +>c : E | F + +var rf4 = a >> c; +>rf4 : number +>a >> c : number +>a : any +>c : E | F + +var rf5 = b >> c; +>rf5 : number +>b >> c : number +>b : number +>c : E | F + +var rf6 = E.a >> a; +>rf6 : number +>E.a >> a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rf7 = E.a >> b; +>rf7 : number +>E.a >> b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rf8 = E.a >> E.b; +>rf8 : number +>E.a >> E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rf9 = E.a >> 1; +>rf9 : number +>E.a >> 1 : number +>E.a : E +>E : typeof E +>a : E + +var rf10 = a >> E.b; +>rf10 : number +>a >> E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rf11 = b >> E.b; +>rf11 : number +>b >> E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rf12 = 1 >> E.b; +>rf12 : number +>1 >> E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator >>> +var rg1 = c >>> a; +>rg1 : number +>c >>> a : number +>c : E | F +>a : any + +var rg2 = c >>> b; +>rg2 : number +>c >>> b : number +>c : E | F +>b : number + +var rg3 = c >>> c; +>rg3 : number +>c >>> c : number +>c : E | F +>c : E | F + +var rg4 = a >>> c; +>rg4 : number +>a >>> c : number +>a : any +>c : E | F + +var rg5 = b >>> c; +>rg5 : number +>b >>> c : number +>b : number +>c : E | F + +var rg6 = E.a >>> a; +>rg6 : number +>E.a >>> a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rg7 = E.a >>> b; +>rg7 : number +>E.a >>> b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rg8 = E.a >>> E.b; +>rg8 : number +>E.a >>> E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rg9 = E.a >>> 1; +>rg9 : number +>E.a >>> 1 : number +>E.a : E +>E : typeof E +>a : E + +var rg10 = a >>> E.b; +>rg10 : number +>a >>> E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rg11 = b >>> E.b; +>rg11 : number +>b >>> E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rg12 = 1 >>> E.b; +>rg12 : number +>1 >>> E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator & +var rh1 = c & a; +>rh1 : number +>c & a : number +>c : E | F +>a : any + +var rh2 = c & b; +>rh2 : number +>c & b : number +>c : E | F +>b : number + +var rh3 = c & c; +>rh3 : number +>c & c : number +>c : E | F +>c : E | F + +var rh4 = a & c; +>rh4 : number +>a & c : number +>a : any +>c : E | F + +var rh5 = b & c; +>rh5 : number +>b & c : number +>b : number +>c : E | F + +var rh6 = E.a & a; +>rh6 : number +>E.a & a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rh7 = E.a & b; +>rh7 : number +>E.a & b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rh8 = E.a & E.b; +>rh8 : number +>E.a & E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rh9 = E.a & 1; +>rh9 : number +>E.a & 1 : number +>E.a : E +>E : typeof E +>a : E + +var rh10 = a & E.b; +>rh10 : number +>a & E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rh11 = b & E.b; +>rh11 : number +>b & E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rh12 = 1 & E.b; +>rh12 : number +>1 & E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator ^ +var ri1 = c ^ a; +>ri1 : number +>c ^ a : number +>c : E | F +>a : any + +var ri2 = c ^ b; +>ri2 : number +>c ^ b : number +>c : E | F +>b : number + +var ri3 = c ^ c; +>ri3 : number +>c ^ c : number +>c : E | F +>c : E | F + +var ri4 = a ^ c; +>ri4 : number +>a ^ c : number +>a : any +>c : E | F + +var ri5 = b ^ c; +>ri5 : number +>b ^ c : number +>b : number +>c : E | F + +var ri6 = E.a ^ a; +>ri6 : number +>E.a ^ a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var ri7 = E.a ^ b; +>ri7 : number +>E.a ^ b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var ri8 = E.a ^ E.b; +>ri8 : number +>E.a ^ E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var ri9 = E.a ^ 1; +>ri9 : number +>E.a ^ 1 : number +>E.a : E +>E : typeof E +>a : E + +var ri10 = a ^ E.b; +>ri10 : number +>a ^ E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var ri11 = b ^ E.b; +>ri11 : number +>b ^ E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var ri12 = 1 ^ E.b; +>ri12 : number +>1 ^ E.b : number +>E.b : E +>E : typeof E +>b : E + +// operator | +var rj1 = c | a; +>rj1 : number +>c | a : number +>c : E | F +>a : any + +var rj2 = c | b; +>rj2 : number +>c | b : number +>c : E | F +>b : number + +var rj3 = c | c; +>rj3 : number +>c | c : number +>c : E | F +>c : E | F + +var rj4 = a | c; +>rj4 : number +>a | c : number +>a : any +>c : E | F + +var rj5 = b | c; +>rj5 : number +>b | c : number +>b : number +>c : E | F + +var rj6 = E.a | a; +>rj6 : number +>E.a | a : number +>E.a : E +>E : typeof E +>a : E +>a : any + +var rj7 = E.a | b; +>rj7 : number +>E.a | b : number +>E.a : E +>E : typeof E +>a : E +>b : number + +var rj8 = E.a | E.b; +>rj8 : number +>E.a | E.b : number +>E.a : E +>E : typeof E +>a : E +>E.b : E +>E : typeof E +>b : E + +var rj9 = E.a | 1; +>rj9 : number +>E.a | 1 : number +>E.a : E +>E : typeof E +>a : E + +var rj10 = a | E.b; +>rj10 : number +>a | E.b : number +>a : any +>E.b : E +>E : typeof E +>b : E + +var rj11 = b | E.b; +>rj11 : number +>b | E.b : number +>b : number +>E.b : E +>E : typeof E +>b : E + +var rj12 = 1 | E.b; +>rj12 : number +>1 | E.b : number +>E.b : E +>E : typeof E +>b : E + diff --git a/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt b/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt index 5f538eef40cbd..9df5357767f17 100644 --- a/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt @@ -1,10 +1,8 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. -tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(15,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. -tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(18,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter @@ -21,7 +19,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter -==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (21 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ==== enum E { a } var x: any; @@ -43,8 +41,6 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv ~~ !!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. var ra4 = a4 in x; - ~~ -!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. var ra5 = null in x; ~~~~ !!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. @@ -52,8 +48,6 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv ~~~~~~~~~ !!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. var ra7 = E.a in x; - ~~~ -!!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. var ra8 = false in x; ~~~~~ !!! error TS2360: The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'. diff --git a/tests/baselines/reference/propertyAccess.errors.txt b/tests/baselines/reference/propertyAccess.errors.txt index fefe929196c09..5cffcbec64c40 100644 --- a/tests/baselines/reference/propertyAccess.errors.txt +++ b/tests/baselines/reference/propertyAccess.errors.txt @@ -1,16 +1,16 @@ -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(9,22): error TS2304: Cannot find name 'HTMLElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(10,22): error TS2304: Cannot find name 'HTMLDivElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(37,14): error TS2339: Property 'qqq' does not exist on type '{ 10: string; x: string; y: number; z: { n: string; m: number; o: () => boolean; }; 'literal property': number; }'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(72,19): error TS2304: Cannot find name 'window'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(109,18): error TS2304: Cannot find name 'window'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(117,9): error TS2304: Cannot find name 'HTMLDivElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(121,9): error TS2304: Cannot find name 'HTMLDivElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(125,9): error TS2304: Cannot find name 'HTMLElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(129,9): error TS2304: Cannot find name 'HTMLElement'. -tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): error TS2304: Cannot find name 'window'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(45,14): error TS2339: Property 'qqq' does not exist on type '{ 10: string; x: string; y: number; z: { n: string; m: number; o: () => boolean; }; 'literal property': number; }'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(80,10): error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(117,10): error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. -==== tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts (10 errors) ==== +==== tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts (4 errors) ==== + class A { + a: number; + } + class B extends A { + b: number; + } enum Compass { North, South, East, West } @@ -19,12 +19,8 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): er var strIndex: { [n: string]: Compass } = { 'N': Compass.North, 'E': Compass.East }; var bothIndex: { - [n: string]: HTMLElement; - ~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLElement'. - [m: number]: HTMLDivElement; - ~~~~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLDivElement'. + [n: string]: A; + [m: number]: B; }; function noIndex() { } @@ -37,6 +33,8 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): er 'literal property': 100 }; var anyVar: any = {}; + var stringOrNumber: string | number; + var someObject: { name: string }; // Assign to a property access obj.y = 4; @@ -88,9 +86,9 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): er var kk: any; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature - var ll = numIndex[window]; // Error - ~~~~~~ -!!! error TS2304: Cannot find name 'window'. + var ll = numIndex[someObject]; // Error + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. // Bracket notation property access using string value on type with string index signature and no numeric index signature var mm = strIndex['N']; @@ -127,9 +125,9 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): er var tt: any; // Bracket notation property access using values of other types on type with no index signatures - var uu = noIndex[window]; // Error - ~~~~~~ -!!! error TS2304: Cannot find name 'window'. + var uu = noIndex[someObject]; // Error + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. // Bracket notation property access using numeric value on type with numeric index signature and string index signature var vv = noIndex[32]; @@ -137,29 +135,31 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(132,22): er // Bracket notation property access using enum value on type with numeric index signature and string index signature var ww = bothIndex[Compass.East]; - var ww: HTMLDivElement; - ~~~~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLDivElement'. + var ww: B; // Bracket notation property access using value of type 'any' on type with numeric index signature and string index signature var xx = bothIndex[null]; - var xx: HTMLDivElement; - ~~~~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLDivElement'. + var xx: B; // Bracket notation property access using string value on type with numeric index signature and string index signature var yy = bothIndex['foo']; - var yy: HTMLElement; - ~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLElement'. + var yy: A; // Bracket notation property access using numeric string value on type with numeric index signature and string index signature var zz = bothIndex['1.0']; - var zz: HTMLElement; - ~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'HTMLElement'. + var zz: A; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature and string index signature - var zzzz = bothIndex[window]; // Error - ~~~~~~ -!!! error TS2304: Cannot find name 'window'. \ No newline at end of file + var zzzz = bothIndex[someObject]; // Error + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2342: An index expression argument must be of type 'string', 'number', or 'any'. + + var x1 = numIndex[stringOrNumber]; + var x1: any; + + var x2 = strIndex[stringOrNumber]; + var x2: Compass; + + var x3 = bothIndex[stringOrNumber]; + var x3: A; + \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccess.js b/tests/baselines/reference/propertyAccess.js index 594bdcd84c29b..e0b89f39de0f1 100644 --- a/tests/baselines/reference/propertyAccess.js +++ b/tests/baselines/reference/propertyAccess.js @@ -1,4 +1,10 @@ //// [propertyAccess.ts] +class A { + a: number; +} +class B extends A { + b: number; +} enum Compass { North, South, East, West } @@ -7,8 +13,8 @@ var numIndex: { [n: number]: string } = { 3: 'three', 'three': 'three' }; var strIndex: { [n: string]: Compass } = { 'N': Compass.North, 'E': Compass.East }; var bothIndex: { - [n: string]: HTMLElement; - [m: number]: HTMLDivElement; + [n: string]: A; + [m: number]: B; }; function noIndex() { } @@ -21,6 +27,8 @@ var obj = { 'literal property': 100 }; var anyVar: any = {}; +var stringOrNumber: string | number; +var someObject: { name: string }; // Assign to a property access obj.y = 4; @@ -70,7 +78,7 @@ var kk = numIndex['what']; var kk: any; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature -var ll = numIndex[window]; // Error +var ll = numIndex[someObject]; // Error // Bracket notation property access using string value on type with string index signature and no numeric index signature var mm = strIndex['N']; @@ -107,7 +115,7 @@ var tt = noIndex[null]; var tt: any; // Bracket notation property access using values of other types on type with no index signatures -var uu = noIndex[window]; // Error +var uu = noIndex[someObject]; // Error // Bracket notation property access using numeric value on type with numeric index signature and string index signature var vv = noIndex[32]; @@ -115,24 +123,52 @@ var vv: any; // Bracket notation property access using enum value on type with numeric index signature and string index signature var ww = bothIndex[Compass.East]; -var ww: HTMLDivElement; +var ww: B; // Bracket notation property access using value of type 'any' on type with numeric index signature and string index signature var xx = bothIndex[null]; -var xx: HTMLDivElement; +var xx: B; // Bracket notation property access using string value on type with numeric index signature and string index signature var yy = bothIndex['foo']; -var yy: HTMLElement; +var yy: A; // Bracket notation property access using numeric string value on type with numeric index signature and string index signature var zz = bothIndex['1.0']; -var zz: HTMLElement; +var zz: A; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature and string index signature -var zzzz = bothIndex[window]; // Error +var zzzz = bothIndex[someObject]; // Error + +var x1 = numIndex[stringOrNumber]; +var x1: any; + +var x2 = strIndex[stringOrNumber]; +var x2: Compass; + +var x3 = bothIndex[stringOrNumber]; +var x3: A; + //// [propertyAccess.js] +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +})(A); var Compass; (function (Compass) { Compass[Compass["North"] = 0] = "North"; @@ -153,6 +189,8 @@ var obj = { 'literal property': 100 }; var anyVar = {}; +var stringOrNumber; +var someObject; // Assign to a property access obj.y = 4; // Property access on value of type 'any' @@ -188,7 +226,7 @@ var jj; var kk = numIndex['what']; var kk; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature -var ll = numIndex[window]; // Error +var ll = numIndex[someObject]; // Error // Bracket notation property access using string value on type with string index signature and no numeric index signature var mm = strIndex['N']; var mm; @@ -216,7 +254,7 @@ var ss; var tt = noIndex[null]; var tt; // Bracket notation property access using values of other types on type with no index signatures -var uu = noIndex[window]; // Error +var uu = noIndex[someObject]; // Error // Bracket notation property access using numeric value on type with numeric index signature and string index signature var vv = noIndex[32]; var vv; @@ -233,4 +271,10 @@ var yy; var zz = bothIndex['1.0']; var zz; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature and string index signature -var zzzz = bothIndex[window]; // Error +var zzzz = bothIndex[someObject]; // Error +var x1 = numIndex[stringOrNumber]; +var x1; +var x2 = strIndex[stringOrNumber]; +var x2; +var x3 = bothIndex[stringOrNumber]; +var x3; diff --git a/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNumberAndEnum.ts b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNumberAndEnum.ts index 09c4bee8a7ad7..82b8fcd7fc5ba 100644 --- a/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNumberAndEnum.ts +++ b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNumberAndEnum.ts @@ -1,7 +1,9 @@ enum E { a, b } +enum F { c, d } var a: number; var b: E; +var c: E | F; var r1 = a + a; var r2 = a + b; @@ -11,4 +13,11 @@ var r4 = b + b; var r5 = 0 + a; var r6 = E.a + 0; var r7 = E.a + E.b; -var r8 = E['a'] + E['b']; \ No newline at end of file +var r8 = E['a'] + E['b']; +var r9 = E['a'] + F['c']; + +var r10 = a + c; +var r11 = c + a; +var r12 = b + c; +var r13 = c + b; +var r14 = c + c; diff --git a/tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithEnumUnion.ts b/tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithEnumUnion.ts new file mode 100644 index 0000000000000..4a8898cc9f263 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithEnumUnion.ts @@ -0,0 +1,154 @@ +// operands of an enum type are treated as having the primitive type Number. + +enum E { + a, + b +} +enum F { + c, + d +} + +var a: any; +var b: number; +var c: E | F; + +// operator * +var ra1 = c * a; +var ra2 = c * b; +var ra3 = c * c; +var ra4 = a * c; +var ra5 = b * c; +var ra6 = E.a * a; +var ra7 = E.a * b; +var ra8 = E.a * E.b; +var ra9 = E.a * 1; +var ra10 = a * E.b; +var ra11 = b * E.b; +var ra12 = 1 * E.b; + +// operator / +var rb1 = c / a; +var rb2 = c / b; +var rb3 = c / c; +var rb4 = a / c; +var rb5 = b / c; +var rb6 = E.a / a; +var rb7 = E.a / b; +var rb8 = E.a / E.b; +var rb9 = E.a / 1; +var rb10 = a / E.b; +var rb11 = b / E.b; +var rb12 = 1 / E.b; + +// operator % +var rc1 = c % a; +var rc2 = c % b; +var rc3 = c % c; +var rc4 = a % c; +var rc5 = b % c; +var rc6 = E.a % a; +var rc7 = E.a % b; +var rc8 = E.a % E.b; +var rc9 = E.a % 1; +var rc10 = a % E.b; +var rc11 = b % E.b; +var rc12 = 1 % E.b; + +// operator - +var rd1 = c - a; +var rd2 = c - b; +var rd3 = c - c; +var rd4 = a - c; +var rd5 = b - c; +var rd6 = E.a - a; +var rd7 = E.a - b; +var rd8 = E.a - E.b; +var rd9 = E.a - 1; +var rd10 = a - E.b; +var rd11 = b - E.b; +var rd12 = 1 - E.b; + +// operator << +var re1 = c << a; +var re2 = c << b; +var re3 = c << c; +var re4 = a << c; +var re5 = b << c; +var re6 = E.a << a; +var re7 = E.a << b; +var re8 = E.a << E.b; +var re9 = E.a << 1; +var re10 = a << E.b; +var re11 = b << E.b; +var re12 = 1 << E.b; + +// operator >> +var rf1 = c >> a; +var rf2 = c >> b; +var rf3 = c >> c; +var rf4 = a >> c; +var rf5 = b >> c; +var rf6 = E.a >> a; +var rf7 = E.a >> b; +var rf8 = E.a >> E.b; +var rf9 = E.a >> 1; +var rf10 = a >> E.b; +var rf11 = b >> E.b; +var rf12 = 1 >> E.b; + +// operator >>> +var rg1 = c >>> a; +var rg2 = c >>> b; +var rg3 = c >>> c; +var rg4 = a >>> c; +var rg5 = b >>> c; +var rg6 = E.a >>> a; +var rg7 = E.a >>> b; +var rg8 = E.a >>> E.b; +var rg9 = E.a >>> 1; +var rg10 = a >>> E.b; +var rg11 = b >>> E.b; +var rg12 = 1 >>> E.b; + +// operator & +var rh1 = c & a; +var rh2 = c & b; +var rh3 = c & c; +var rh4 = a & c; +var rh5 = b & c; +var rh6 = E.a & a; +var rh7 = E.a & b; +var rh8 = E.a & E.b; +var rh9 = E.a & 1; +var rh10 = a & E.b; +var rh11 = b & E.b; +var rh12 = 1 & E.b; + +// operator ^ +var ri1 = c ^ a; +var ri2 = c ^ b; +var ri3 = c ^ c; +var ri4 = a ^ c; +var ri5 = b ^ c; +var ri6 = E.a ^ a; +var ri7 = E.a ^ b; +var ri8 = E.a ^ E.b; +var ri9 = E.a ^ 1; +var ri10 = a ^ E.b; +var ri11 = b ^ E.b; +var ri12 = 1 ^ E.b; + +// operator | +var rj1 = c | a; +var rj2 = c | b; +var rj3 = c | c; +var rj4 = a | c; +var rj5 = b | c; +var rj6 = E.a | a; +var rj7 = E.a | b; +var rj8 = E.a | E.b; +var rj9 = E.a | 1; +var rj10 = a | E.b; +var rj11 = b | E.b; +var rj12 = 1 | E.b; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts b/tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts index 62248efaf7cc1..d5ea7e6e06a23 100644 --- a/tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts +++ b/tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts @@ -1,3 +1,9 @@ +class A { + a: number; +} +class B extends A { + b: number; +} enum Compass { North, South, East, West } @@ -6,8 +12,8 @@ var numIndex: { [n: number]: string } = { 3: 'three', 'three': 'three' }; var strIndex: { [n: string]: Compass } = { 'N': Compass.North, 'E': Compass.East }; var bothIndex: { - [n: string]: HTMLElement; - [m: number]: HTMLDivElement; + [n: string]: A; + [m: number]: B; }; function noIndex() { } @@ -20,6 +26,8 @@ var obj = { 'literal property': 100 }; var anyVar: any = {}; +var stringOrNumber: string | number; +var someObject: { name: string }; // Assign to a property access obj.y = 4; @@ -69,7 +77,7 @@ var kk = numIndex['what']; var kk: any; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature -var ll = numIndex[window]; // Error +var ll = numIndex[someObject]; // Error // Bracket notation property access using string value on type with string index signature and no numeric index signature var mm = strIndex['N']; @@ -106,7 +114,7 @@ var tt = noIndex[null]; var tt: any; // Bracket notation property access using values of other types on type with no index signatures -var uu = noIndex[window]; // Error +var uu = noIndex[someObject]; // Error // Bracket notation property access using numeric value on type with numeric index signature and string index signature var vv = noIndex[32]; @@ -114,19 +122,28 @@ var vv: any; // Bracket notation property access using enum value on type with numeric index signature and string index signature var ww = bothIndex[Compass.East]; -var ww: HTMLDivElement; +var ww: B; // Bracket notation property access using value of type 'any' on type with numeric index signature and string index signature var xx = bothIndex[null]; -var xx: HTMLDivElement; +var xx: B; // Bracket notation property access using string value on type with numeric index signature and string index signature var yy = bothIndex['foo']; -var yy: HTMLElement; +var yy: A; // Bracket notation property access using numeric string value on type with numeric index signature and string index signature var zz = bothIndex['1.0']; -var zz: HTMLElement; +var zz: A; // Bracket notation property access using value of other type on type with numeric index signature and no string index signature and string index signature -var zzzz = bothIndex[window]; // Error \ No newline at end of file +var zzzz = bothIndex[someObject]; // Error + +var x1 = numIndex[stringOrNumber]; +var x1: any; + +var x2 = strIndex[stringOrNumber]; +var x2: Compass; + +var x3 = bothIndex[stringOrNumber]; +var x3: A; From 361ea7bef55b5ff4c922e66ab58ec0648c771518 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 21 Jan 2015 14:55:32 -0800 Subject: [PATCH 4/4] Removing unused variable --- src/compiler/checker.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 708b6eaa696f8..1e84c78fce174 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -93,7 +93,6 @@ module ts { var globalTemplateStringsArrayType: ObjectType; var anyArrayType: Type; - var stringOrNumberType: Type; var tupleTypes: Map = {}; var unionTypes: Map = {}; @@ -10071,7 +10070,6 @@ module ts { ? getGlobalType("TemplateStringsArray") : unknownType; anyArrayType = createArrayType(anyType); - stringOrNumberType = getUnionType([stringType, numberType]); }