From 7cb2db7f9efd9d6e3efe1a7fe8e221cdbd6375fd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 24 May 2016 20:09:15 -0700 Subject: [PATCH] Fix #8795: make properties defined in optional constructor paramters optional --- src/compiler/binder.ts | 2 +- .../assignmentCompatability10.errors.txt | 17 ---------- .../optionalParameterProperty.errors.txt | 23 +++++++++++++ .../reference/optionalParameterProperty.js | 32 +++++++++++++++++++ ...opertyParameterWithQuestionMark.errors.txt | 25 ++++++--------- .../propertyParameterWithQuestionMark.js | 16 +++++----- .../compiler/optionalParameterProperty.ts | 11 +++++++ .../propertyParameterWithQuestionMark.ts | 8 ++--- 8 files changed, 89 insertions(+), 45 deletions(-) delete mode 100644 tests/baselines/reference/assignmentCompatability10.errors.txt create mode 100644 tests/baselines/reference/optionalParameterProperty.errors.txt create mode 100644 tests/baselines/reference/optionalParameterProperty.js create mode 100644 tests/cases/compiler/optionalParameterProperty.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 304e77271a7..d05b6c9f82c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2027,7 +2027,7 @@ namespace ts { // containing class. if (isParameterPropertyDeclaration(node)) { const classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); } } diff --git a/tests/baselines/reference/assignmentCompatability10.errors.txt b/tests/baselines/reference/assignmentCompatability10.errors.txt deleted file mode 100644 index 883bf1c277c..00000000000 --- a/tests/baselines/reference/assignmentCompatability10.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -tests/cases/compiler/assignmentCompatability10.ts(9,1): error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type 'classWithPublicAndOptional'. - Property 'two' is optional in type 'interfaceWithPublicAndOptional' but required in type 'classWithPublicAndOptional'. - - -==== tests/cases/compiler/assignmentCompatability10.ts (1 errors) ==== - module __test1__ { - export interface interfaceWithPublicAndOptional { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional = { one: 1 };; - export var __val__obj4 = obj4; - } - module __test2__ { - export class classWithPublicAndOptional { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional(1);; - export var __val__x4 = x4; - } - __test2__.__val__x4 = __test1__.__val__obj4 - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type 'classWithPublicAndOptional'. -!!! error TS2322: Property 'two' is optional in type 'interfaceWithPublicAndOptional' but required in type 'classWithPublicAndOptional'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalParameterProperty.errors.txt b/tests/baselines/reference/optionalParameterProperty.errors.txt new file mode 100644 index 00000000000..d585ff6964d --- /dev/null +++ b/tests/baselines/reference/optionalParameterProperty.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/optionalParameterProperty.ts(6,7): error TS2415: Class 'D' incorrectly extends base class 'C'. + Types of property 'p' are incompatible. + Type 'number | undefined' is not assignable to type 'number'. + Type 'undefined' is not assignable to type 'number'. + + +==== tests/cases/compiler/optionalParameterProperty.ts (1 errors) ==== + + class C { + p: number; + } + + class D extends C { + ~ +!!! error TS2415: Class 'D' incorrectly extends base class 'C'. +!!! error TS2415: Types of property 'p' are incompatible. +!!! error TS2415: Type 'number | undefined' is not assignable to type 'number'. +!!! error TS2415: Type 'undefined' is not assignable to type 'number'. + constructor(public p?: number) { + super(); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/optionalParameterProperty.js b/tests/baselines/reference/optionalParameterProperty.js new file mode 100644 index 00000000000..48cefeef22c --- /dev/null +++ b/tests/baselines/reference/optionalParameterProperty.js @@ -0,0 +1,32 @@ +//// [optionalParameterProperty.ts] + +class C { + p: number; +} + +class D extends C { + constructor(public p?: number) { + super(); + } +} + + +//// [optionalParameterProperty.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + return C; +}()); +var D = (function (_super) { + __extends(D, _super); + function D(p) { + _super.call(this); + this.p = p; + } + return D; +}(C)); diff --git a/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt b/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt index b3970c216eb..76dfb503e52 100644 --- a/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt +++ b/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt @@ -1,22 +1,17 @@ -tests/cases/compiler/propertyParameterWithQuestionMark.ts(6,5): error TS2322: Type '{}' is not assignable to type 'C'. - Property 'x' is missing in type '{}'. -tests/cases/compiler/propertyParameterWithQuestionMark.ts(8,1): error TS2322: Type '{ x?: any; }' is not assignable to type 'C'. - Property 'x' is optional in type '{ x?: any; }' but required in type 'C'. +tests/cases/compiler/propertyParameterWithQuestionMark.ts(9,5): error TS2322: Type 'C' is not assignable to type '{ x: any; }'. + Property 'x' is optional in type 'C' but required in type '{ x: any; }'. -==== tests/cases/compiler/propertyParameterWithQuestionMark.ts (2 errors) ==== +==== tests/cases/compiler/propertyParameterWithQuestionMark.ts (1 errors) ==== class C { constructor(public x?) { } } - // x should not be an optional property - var v: C = {}; // Should fail - ~ -!!! error TS2322: Type '{}' is not assignable to type 'C'. -!!! error TS2322: Property 'x' is missing in type '{}'. + // x should be an optional property + var v: C = {}; // Should succeed var v2: { x? } - v = v2; // Should fail - ~ -!!! error TS2322: Type '{ x?: any; }' is not assignable to type 'C'. -!!! error TS2322: Property 'x' is optional in type '{ x?: any; }' but required in type 'C'. - var v3: { x } = new C; // Should succeed \ No newline at end of file + v = v2; // Should succeed + var v3: { x } = new C; // Should fail + ~~ +!!! error TS2322: Type 'C' is not assignable to type '{ x: any; }'. +!!! error TS2322: Property 'x' is optional in type 'C' but required in type '{ x: any; }'. \ No newline at end of file diff --git a/tests/baselines/reference/propertyParameterWithQuestionMark.js b/tests/baselines/reference/propertyParameterWithQuestionMark.js index 511062663e8..b72638387dd 100644 --- a/tests/baselines/reference/propertyParameterWithQuestionMark.js +++ b/tests/baselines/reference/propertyParameterWithQuestionMark.js @@ -3,11 +3,11 @@ class C { constructor(public x?) { } } -// x should not be an optional property -var v: C = {}; // Should fail +// x should be an optional property +var v: C = {}; // Should succeed var v2: { x? } -v = v2; // Should fail -var v3: { x } = new C; // Should succeed +v = v2; // Should succeed +var v3: { x } = new C; // Should fail //// [propertyParameterWithQuestionMark.js] var C = (function () { @@ -16,8 +16,8 @@ var C = (function () { } return C; }()); -// x should not be an optional property -var v = {}; // Should fail +// x should be an optional property +var v = {}; // Should succeed var v2; -v = v2; // Should fail -var v3 = new C; // Should succeed +v = v2; // Should succeed +var v3 = new C; // Should fail diff --git a/tests/cases/compiler/optionalParameterProperty.ts b/tests/cases/compiler/optionalParameterProperty.ts new file mode 100644 index 00000000000..1f547d4af26 --- /dev/null +++ b/tests/cases/compiler/optionalParameterProperty.ts @@ -0,0 +1,11 @@ +// @strictNullChecks: true + +class C { + p: number; +} + +class D extends C { + constructor(public p?: number) { + super(); + } +} diff --git a/tests/cases/compiler/propertyParameterWithQuestionMark.ts b/tests/cases/compiler/propertyParameterWithQuestionMark.ts index 1a0eedb799e..ce2d88669c3 100644 --- a/tests/cases/compiler/propertyParameterWithQuestionMark.ts +++ b/tests/cases/compiler/propertyParameterWithQuestionMark.ts @@ -2,8 +2,8 @@ class C { constructor(public x?) { } } -// x should not be an optional property -var v: C = {}; // Should fail +// x should be an optional property +var v: C = {}; // Should succeed var v2: { x? } -v = v2; // Should fail -var v3: { x } = new C; // Should succeed \ No newline at end of file +v = v2; // Should succeed +var v3: { x } = new C; // Should fail \ No newline at end of file