Fix #8795: make properties defined in optional constructor paramters optional

This commit is contained in:
Mohamed Hegazy 2016-05-24 20:09:15 -07:00
parent 02c584bcc6
commit 7cb2db7f9e
8 changed files with 89 additions and 45 deletions

View File

@ -2027,7 +2027,7 @@ namespace ts {
// containing class.
if (isParameterPropertyDeclaration(node)) {
const classDeclaration = <ClassLikeDeclaration>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);
}
}

View File

@ -1,17 +0,0 @@
tests/cases/compiler/assignmentCompatability10.ts(9,1): error TS2322: Type 'interfaceWithPublicAndOptional<number, string>' is not assignable to type 'classWithPublicAndOptional<number, string>'.
Property 'two' is optional in type 'interfaceWithPublicAndOptional<number, string>' but required in type 'classWithPublicAndOptional<number, string>'.
==== tests/cases/compiler/assignmentCompatability10.ts (1 errors) ====
module __test1__ {
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
export var __val__obj4 = obj4;
}
module __test2__ {
export class classWithPublicAndOptional<T,U> { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional<number, string>(1);;
export var __val__x4 = x4;
}
__test2__.__val__x4 = __test1__.__val__obj4
~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'interfaceWithPublicAndOptional<number, string>' is not assignable to type 'classWithPublicAndOptional<number, string>'.
!!! error TS2322: Property 'two' is optional in type 'interfaceWithPublicAndOptional<number, string>' but required in type 'classWithPublicAndOptional<number, string>'.

View File

@ -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();
}
}

View File

@ -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));

View File

@ -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
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; }'.

View File

@ -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

View File

@ -0,0 +1,11 @@
// @strictNullChecks: true
class C {
p: number;
}
class D extends C {
constructor(public p?: number) {
super();
}
}

View File

@ -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
v = v2; // Should succeed
var v3: { x } = new C; // Should fail