diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7604c709fbc71..06c4ca9190faa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7189,7 +7189,7 @@ module ts { checkVariableLikeDeclaration(node); var func = getContainingFunction(node); - if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) { + if (node.flags & NodeFlags.AccessibilityModifier) { func = getContainingFunction(node); if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) { error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -7208,17 +7208,20 @@ module ts { checkGrammarIndexSignature(node); } // TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled - else if (node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ConstructorType || + else if (node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ConstructorType || node.kind === SyntaxKind.CallSignature || node.kind === SyntaxKind.Constructor || node.kind === SyntaxKind.ConstructSignature){ checkGrammarFunctionLikeDeclaration(node); } checkTypeParameters(node.typeParameters); + forEach(node.parameters, checkParameter); + if (node.type) { checkSourceElement(node.type); } + if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); if (compilerOptions.noImplicitAny && !node.type) { @@ -10169,6 +10172,9 @@ module ts { else if (node.kind === SyntaxKind.InterfaceDeclaration && flags & NodeFlags.Ambient) { return grammarErrorOnNode(lastDeclare, Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare"); } + else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.AccessibilityModifier) && isBindingPattern((node).name)) { + return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_a_binding_pattern); + } } function checkGrammarForDisallowedTrailingComma(list: NodeArray): boolean { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 2a342fa17d2d0..80e1505569d74 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -146,6 +146,7 @@ module ts { Modifiers_cannot_appear_here: { code: 1184, category: DiagnosticCategory.Error, key: "Modifiers cannot appear here." }, Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." }, A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." }, + A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index efb2bfe7e9444..704e3ada25ff3 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -224,7 +224,7 @@ "A 'declare' modifier cannot be used with an import declaration.": { "category": "Error", "code": 1079, - "isEarly": true + "isEarly": true }, "Invalid 'reference' directive syntax.": { "category": "Error", @@ -659,7 +659,7 @@ "An implementation cannot be declared in ambient contexts.": { "category": "Error", "code": 1184, - "isEarly": true + "isEarly": true }, "Modifiers cannot appear here.": { "category": "Error", @@ -673,6 +673,10 @@ "category": "Error", "code": 1186 }, + "A parameter property may not be a binding pattern.": { + "category": "Error", + "code": 1187 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b70c4a7a1d5cb..5ae44e5ff398a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1395,7 +1395,10 @@ module ts { } function canFollowModifier(): boolean { - return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName(); + return token === SyntaxKind.OpenBracketToken + || token === SyntaxKind.OpenBraceToken + || token === SyntaxKind.AsteriskToken + || isLiteralPropertyName(); } // True if positioned at the start of a list element diff --git a/tests/baselines/reference/destructuringParameterProperties1.errors.txt b/tests/baselines/reference/destructuringParameterProperties1.errors.txt new file mode 100644 index 0000000000000..b8f3a22b4c580 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties1.errors.txt @@ -0,0 +1,71 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(2,17): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(9,17): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(16,17): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(22,26): error TS2339: Property 'x' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(22,35): error TS2339: Property 'y' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(22,43): error TS2339: Property 'y' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(22,52): error TS2339: Property 'z' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(25,30): error TS2339: Property 'x' does not exist on type 'C2'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(25,36): error TS2339: Property 'y' does not exist on type 'C2'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(25,42): error TS2339: Property 'z' does not exist on type 'C2'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(29,30): error TS2339: Property 'x' does not exist on type 'C3'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(29,36): error TS2339: Property 'y' does not exist on type 'C3'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts(29,42): error TS2339: Property 'z' does not exist on type 'C3'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts (13 errors) ==== + class C1 { + constructor(public [x, y, z]: string[]) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + } + } + + type TupleType1 = [string, number, boolean]; + + class C2 { + constructor(public [x, y, z]: TupleType1) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + } + } + + type ObjType1 = { x: number; y: string; z: boolean } + + class C3 { + constructor(public { x, y, z }: ObjType1) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + } + } + + var c1 = new C1([]); + c1 = new C1(["larry", "{curly}", "moe"]); + var useC1Properties = c1.x === c1.y && c1.y === c1.z; + ~ +!!! error TS2339: Property 'x' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'z' does not exist on type 'C1'. + + var c2 = new C2(["10", 10, !!10]); + var [c2_x, c2_y, c2_z] = [c2.x, c2.y, c2.z]; + ~ +!!! error TS2339: Property 'x' does not exist on type 'C2'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'C2'. + ~ +!!! error TS2339: Property 'z' does not exist on type 'C2'. + + var c3 = new C3({x: 0, y: "", z: false}); + c3 = new C3({x: 0, "y": "y", z: true}); + var [c3_x, c3_y, c3_z] = [c3.x, c3.y, c3.z]; + ~ +!!! error TS2339: Property 'x' does not exist on type 'C3'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'C3'. + ~ +!!! error TS2339: Property 'z' does not exist on type 'C3'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties1.js b/tests/baselines/reference/destructuringParameterProperties1.js new file mode 100644 index 0000000000000..cc16cc78de59d --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties1.js @@ -0,0 +1,61 @@ +//// [destructuringParameterProperties1.ts] +class C1 { + constructor(public [x, y, z]: string[]) { + } +} + +type TupleType1 = [string, number, boolean]; + +class C2 { + constructor(public [x, y, z]: TupleType1) { + } +} + +type ObjType1 = { x: number; y: string; z: boolean } + +class C3 { + constructor(public { x, y, z }: ObjType1) { + } +} + +var c1 = new C1([]); +c1 = new C1(["larry", "{curly}", "moe"]); +var useC1Properties = c1.x === c1.y && c1.y === c1.z; + +var c2 = new C2(["10", 10, !!10]); +var [c2_x, c2_y, c2_z] = [c2.x, c2.y, c2.z]; + +var c3 = new C3({x: 0, y: "", z: false}); +c3 = new C3({x: 0, "y": "y", z: true}); +var [c3_x, c3_y, c3_z] = [c3.x, c3.y, c3.z]; + +//// [destructuringParameterProperties1.js] +var C1 = (function () { + function C1(_a) { + var x = _a[0], y = _a[1], z = _a[2]; + this.[x, y, z] = [x, y, z]; + } + return C1; +})(); +var C2 = (function () { + function C2(_a) { + var x = _a[0], y = _a[1], z = _a[2]; + this.[x, y, z] = [x, y, z]; + } + return C2; +})(); +var C3 = (function () { + function C3(_a) { + var x = _a.x, y = _a.y, z = _a.z; + this.{ x, y, z } = { x, y, z }; + } + return C3; +})(); +var c1 = new C1([]); +c1 = new C1(["larry", "{curly}", "moe"]); +var useC1Properties = c1.x === c1.y && c1.y === c1.z; +var c2 = new C2(["10", 10, !!10]); +var _a = [c2.x, c2.y, c2.z], c2_x = _a[0], c2_y = _a[1], c2_z = _a[2]; +var c3 = new C3({ x: 0, y: "", z: false }); +c3 = new C3({ x: 0, "y": "y", z: true }); +var _b = [c3.x, c3.y, c3.z], c3_x = _b[0], c3_y = _b[1], c3_z = _b[2]; diff --git a/tests/baselines/reference/destructuringParameterProperties2.errors.txt b/tests/baselines/reference/destructuringParameterProperties2.errors.txt new file mode 100644 index 0000000000000..61c0e61611aa7 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties2.errors.txt @@ -0,0 +1,56 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(2,36): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(3,59): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(3,83): error TS2339: Property 'c' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(4,18): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(9,21): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(13,21): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(17,21): error TS2339: Property 'c' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(21,27): error TS2345: Argument of type '[number, undefined, string]' is not assignable to parameter of type '[number, string, boolean]'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts (8 errors) ==== + class C1 { + constructor(private k: number, private [a, b, c]: [number, string, boolean]) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + this.a = a || k; + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + } + + public getA() { + return this.a + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + + public getB() { + return this.b + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + } + + public getC() { + return this.c; + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + } + } + + var x = new C1(undefined, [0, undefined, ""]); + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, undefined, string]' is not assignable to parameter of type '[number, string, boolean]'. + var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + + var y = new C1(10, [0, "", true]); + var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + + var z = new C1(10, [undefined, "", null]); + var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties2.js b/tests/baselines/reference/destructuringParameterProperties2.js new file mode 100644 index 0000000000000..27e190af62f2c --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties2.js @@ -0,0 +1,58 @@ +//// [destructuringParameterProperties2.ts] +class C1 { + constructor(private k: number, private [a, b, c]: [number, string, boolean]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +var x = new C1(undefined, [0, undefined, ""]); +var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + +var y = new C1(10, [0, "", true]); +var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + +var z = new C1(10, [undefined, "", null]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + + +//// [destructuringParameterProperties2.js] +var C1 = (function () { + function C1(k, _a) { + var a = _a[0], b = _a[1], c = _a[2]; + this.k = k; + this.[a, b, c] = [a, b, c]; + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + C1.prototype.getA = function () { + return this.a; + }; + C1.prototype.getB = function () { + return this.b; + }; + C1.prototype.getC = function () { + return this.c; + }; + return C1; +})(); +var x = new C1(undefined, [0, undefined, ""]); +var _a = [x.getA(), x.getB(), x.getC()], x_a = _a[0], x_b = _a[1], x_c = _a[2]; +var y = new C1(10, [0, "", true]); +var _b = [y.getA(), y.getB(), y.getC()], y_a = _b[0], y_b = _b[1], y_c = _b[2]; +var z = new C1(10, [undefined, "", null]); +var _c = [z.getA(), z.getB(), z.getC()], z_a = _c[0], z_b = _c[1], z_c = _c[2]; diff --git a/tests/baselines/reference/destructuringParameterProperties3.errors.txt b/tests/baselines/reference/destructuringParameterProperties3.errors.txt new file mode 100644 index 0000000000000..73d7dab2a3897 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties3.errors.txt @@ -0,0 +1,56 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(2,31): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(3,59): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(3,83): error TS2339: Property 'c' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(4,18): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(9,21): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(13,21): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts(17,21): error TS2339: Property 'c' does not exist on type 'C1'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts (7 errors) ==== + class C1 { + constructor(private k: T, private [a, b, c]: [T,U,V]) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + this.a = a || k; + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + } + + public getA() { + return this.a + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + + public getB() { + return this.b + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + } + + public getC() { + return this.c; + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + } + } + + var x = new C1(undefined, [0, true, ""]); + var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + + var y = new C1(10, [0, true, true]); + var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + + var z = new C1(10, [undefined, "", ""]); + var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + + var w = new C1(10, [undefined, undefined, undefined]); + var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties3.js b/tests/baselines/reference/destructuringParameterProperties3.js new file mode 100644 index 0000000000000..fe9e69d7e5bc0 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties3.js @@ -0,0 +1,63 @@ +//// [destructuringParameterProperties3.ts] +class C1 { + constructor(private k: T, private [a, b, c]: [T,U,V]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +var x = new C1(undefined, [0, true, ""]); +var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + +var y = new C1(10, [0, true, true]); +var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + +var z = new C1(10, [undefined, "", ""]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + +var w = new C1(10, [undefined, undefined, undefined]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + + +//// [destructuringParameterProperties3.js] +var C1 = (function () { + function C1(k, _a) { + var a = _a[0], b = _a[1], c = _a[2]; + this.k = k; + this.[a, b, c] = [a, b, c]; + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + C1.prototype.getA = function () { + return this.a; + }; + C1.prototype.getB = function () { + return this.b; + }; + C1.prototype.getC = function () { + return this.c; + }; + return C1; +})(); +var x = new C1(undefined, [0, true, ""]); +var _a = [x.getA(), x.getB(), x.getC()], x_a = _a[0], x_b = _a[1], x_c = _a[2]; +var y = new C1(10, [0, true, true]); +var _b = [y.getA(), y.getB(), y.getC()], y_a = _b[0], y_b = _b[1], y_c = _b[2]; +var z = new C1(10, [undefined, "", ""]); +var _c = [z.getA(), z.getB(), z.getC()], z_a = _c[0], z_b = _c[1], z_c = _c[2]; +var w = new C1(10, [undefined, undefined, undefined]); +var _d = [z.getA(), z.getB(), z.getC()], z_a = _d[0], z_b = _d[1], z_c = _d[2]; diff --git a/tests/baselines/reference/destructuringParameterProperties4.errors.txt b/tests/baselines/reference/destructuringParameterProperties4.errors.txt new file mode 100644 index 0000000000000..04f6f82b5df29 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties4.errors.txt @@ -0,0 +1,60 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(3,31): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(4,59): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(4,83): error TS2339: Property 'c' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(5,18): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(10,21): error TS2339: Property 'a' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(14,21): error TS2339: Property 'b' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(18,21): error TS2339: Property 'c' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(24,24): error TS2339: Property 'a' does not exist on type 'C2'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(24,34): error TS2339: Property 'b' does not exist on type 'C2'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts(24,44): error TS2339: Property 'c' does not exist on type 'C2'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts (10 errors) ==== + + class C1 { + constructor(private k: T, protected [a, b, c]: [T,U,V]) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + this.a = a || k; + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + } + + public getA() { + return this.a + ~ +!!! error TS2339: Property 'a' does not exist on type 'C1'. + } + + public getB() { + return this.b + ~ +!!! error TS2339: Property 'b' does not exist on type 'C1'. + } + + public getC() { + return this.c; + ~ +!!! error TS2339: Property 'c' does not exist on type 'C1'. + } + } + + class C2 extends C1 { + public doSomethingWithSuperProperties() { + return `${this.a} ${this.b} ${this.c}`; + ~ +!!! error TS2339: Property 'a' does not exist on type 'C2'. + ~ +!!! error TS2339: Property 'b' does not exist on type 'C2'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'C2'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties4.js b/tests/baselines/reference/destructuringParameterProperties4.js new file mode 100644 index 0000000000000..6da6f53a4fe04 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties4.js @@ -0,0 +1,65 @@ +//// [destructuringParameterProperties4.ts] + +class C1 { + constructor(private k: T, protected [a, b, c]: [T,U,V]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +class C2 extends C1 { + public doSomethingWithSuperProperties() { + return `${this.a} ${this.b} ${this.c}`; + } +} + + +//// [destructuringParameterProperties4.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 C1 = (function () { + function C1(k, [a, b, c]) { + this.k = k; + this.[a, b, c] = [a, b, c]; + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + C1.prototype.getA = function () { + return this.a; + }; + C1.prototype.getB = function () { + return this.b; + }; + C1.prototype.getC = function () { + return this.c; + }; + return C1; +})(); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + _super.apply(this, arguments); + } + C2.prototype.doSomethingWithSuperProperties = function () { + return `${this.a} ${this.b} ${this.c}`; + }; + return C2; +})(C1); diff --git a/tests/baselines/reference/destructuringParameterProperties5.errors.txt b/tests/baselines/reference/destructuringParameterProperties5.errors.txt new file mode 100644 index 0000000000000..dca02a9a84e3f --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties5.errors.txt @@ -0,0 +1,51 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,17): error TS1187: A parameter property may not be a binding pattern. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,27): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x1' and no string index signature. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,31): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x2' and no string index signature. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(5,35): error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x3' and no string index signature. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,29): error TS2339: Property 'x1' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,40): error TS2339: Property 'x2' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,51): error TS2339: Property 'x3' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,62): error TS2339: Property 'y' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,72): error TS2339: Property 'z' does not exist on type 'C1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,16): error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[{ x: number; y: string; z: boolean; }, number, string]'. + Types of property '0' are incompatible. + Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'. + Property 'x' is missing in type '{ x1: number; x2: string; x3: boolean; }'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (10 errors) ==== + type ObjType1 = { x: number; y: string; z: boolean } + type TupleType1 = [ObjType1, number, string] + + class C1 { + constructor(public [{ x1, x2, x3 }, y, z]: TupleType1) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1187: A parameter property may not be a binding pattern. + ~~ +!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x1' and no string index signature. + ~~ +!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x2' and no string index signature. + ~~ +!!! error TS2459: Type '{ x: number; y: string; z: boolean; }' has no property 'x3' and no string index signature. + var foo: any = x1 || x2 || x3 || y || z; + var bar: any = this.x1 || this.x2 || this.x3 || this.y || this.z; + ~~ +!!! error TS2339: Property 'x1' does not exist on type 'C1'. + ~~ +!!! error TS2339: Property 'x2' does not exist on type 'C1'. + ~~ +!!! error TS2339: Property 'x3' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'C1'. + ~ +!!! error TS2339: Property 'z' does not exist on type 'C1'. + } + } + + var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[{ x: number; y: string; z: boolean; }, number, string]'. +!!! error TS2345: Types of property '0' are incompatible. +!!! error TS2345: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'. +!!! error TS2345: Property 'x' is missing in type '{ x1: number; x2: string; x3: boolean; }'. + var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z]; \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties5.js b/tests/baselines/reference/destructuringParameterProperties5.js new file mode 100644 index 0000000000000..d9b1710ae8935 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterProperties5.js @@ -0,0 +1,26 @@ +//// [destructuringParameterProperties5.ts] +type ObjType1 = { x: number; y: string; z: boolean } +type TupleType1 = [ObjType1, number, string] + +class C1 { + constructor(public [{ x1, x2, x3 }, y, z]: TupleType1) { + var foo: any = x1 || x2 || x3 || y || z; + var bar: any = this.x1 || this.x2 || this.x3 || this.y || this.z; + } +} + +var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]); +var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z]; + +//// [destructuringParameterProperties5.js] +var C1 = (function () { + function C1(_a) { + var _b = _a[0], x1 = _b.x1, x2 = _b.x2, x3 = _b.x3, y = _a[1], z = _a[2]; + this.[{ x1, x2, x3 }, y, z] = [{ x1, x2, x3 }, y, z]; + var foo = x1 || x2 || x3 || y || z; + var bar = this.x1 || this.x2 || this.x3 || this.y || this.z; + } + return C1; +})(); +var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]); +var _a = [a.x1, a.x2, a.x3, a.y, a.z], a_x1 = _a[0], a_x2 = _a[1], a_x3 = _a[2], a_y = _a[3], a_z = _a[4]; diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts new file mode 100644 index 0000000000000..ba73adc9fde21 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties1.ts @@ -0,0 +1,29 @@ +class C1 { + constructor(public [x, y, z]: string[]) { + } +} + +type TupleType1 = [string, number, boolean]; + +class C2 { + constructor(public [x, y, z]: TupleType1) { + } +} + +type ObjType1 = { x: number; y: string; z: boolean } + +class C3 { + constructor(public { x, y, z }: ObjType1) { + } +} + +var c1 = new C1([]); +c1 = new C1(["larry", "{curly}", "moe"]); +var useC1Properties = c1.x === c1.y && c1.y === c1.z; + +var c2 = new C2(["10", 10, !!10]); +var [c2_x, c2_y, c2_z] = [c2.x, c2.y, c2.z]; + +var c3 = new C3({x: 0, y: "", z: false}); +c3 = new C3({x: 0, "y": "y", z: true}); +var [c3_x, c3_y, c3_z] = [c3.x, c3.y, c3.z]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts new file mode 100644 index 0000000000000..b7f37809154be --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts @@ -0,0 +1,28 @@ +class C1 { + constructor(private k: number, private [a, b, c]: [number, string, boolean]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +var x = new C1(undefined, [0, undefined, ""]); +var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + +var y = new C1(10, [0, "", true]); +var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + +var z = new C1(10, [undefined, "", null]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts new file mode 100644 index 0000000000000..6819d024e6a15 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties3.ts @@ -0,0 +1,31 @@ +class C1 { + constructor(private k: T, private [a, b, c]: [T,U,V]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +var x = new C1(undefined, [0, true, ""]); +var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; + +var y = new C1(10, [0, true, true]); +var [y_a, y_b, y_c] = [y.getA(), y.getB(), y.getC()]; + +var z = new C1(10, [undefined, "", ""]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; + +var w = new C1(10, [undefined, undefined, undefined]); +var [z_a, z_b, z_c] = [z.getA(), z.getB(), z.getC()]; diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts new file mode 100644 index 0000000000000..7a83e5f4d4b99 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties4.ts @@ -0,0 +1,27 @@ +// @target: es6 + +class C1 { + constructor(private k: T, protected [a, b, c]: [T,U,V]) { + if ((b === undefined && c === undefined) || (this.b === undefined && this.c === undefined)) { + this.a = a || k; + } + } + + public getA() { + return this.a + } + + public getB() { + return this.b + } + + public getC() { + return this.c; + } +} + +class C2 extends C1 { + public doSomethingWithSuperProperties() { + return `${this.a} ${this.b} ${this.c}`; + } +} diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts new file mode 100644 index 0000000000000..02f9b780ad99d --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts @@ -0,0 +1,12 @@ +type ObjType1 = { x: number; y: string; z: boolean } +type TupleType1 = [ObjType1, number, string] + +class C1 { + constructor(public [{ x1, x2, x3 }, y, z]: TupleType1) { + var foo: any = x1 || x2 || x3 || y || z; + var bar: any = this.x1 || this.x2 || this.x3 || this.y || this.z; + } +} + +var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]); +var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z]; \ No newline at end of file