Merge pull request #8825 from Microsoft/Fix8795-1
Fix #8795: make properties defined in optional constructor parameters optional
This commit is contained in:
commit
6173696b25
10 changed files with 186 additions and 45 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>'.
|
46
tests/baselines/reference/assignmentCompatability10.symbols
Normal file
46
tests/baselines/reference/assignmentCompatability10.symbols
Normal file
|
@ -0,0 +1,46 @@
|
|||
=== tests/cases/compiler/assignmentCompatability10.ts ===
|
||||
module __test1__ {
|
||||
>__test1__ : Symbol(__test1__, Decl(assignmentCompatability10.ts, 0, 0))
|
||||
|
||||
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
|
||||
>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability10.ts, 0, 18))
|
||||
>T : Symbol(T, Decl(assignmentCompatability10.ts, 1, 52))
|
||||
>U : Symbol(U, Decl(assignmentCompatability10.ts, 1, 54))
|
||||
>one : Symbol(interfaceWithPublicAndOptional.one, Decl(assignmentCompatability10.ts, 1, 58))
|
||||
>T : Symbol(T, Decl(assignmentCompatability10.ts, 1, 52))
|
||||
>two : Symbol(interfaceWithPublicAndOptional.two, Decl(assignmentCompatability10.ts, 1, 66))
|
||||
>U : Symbol(U, Decl(assignmentCompatability10.ts, 1, 54))
|
||||
>obj4 : Symbol(obj4, Decl(assignmentCompatability10.ts, 1, 83))
|
||||
>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability10.ts, 0, 18))
|
||||
>one : Symbol(one, Decl(assignmentCompatability10.ts, 1, 139))
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
>__val__obj4 : Symbol(__val__obj4, Decl(assignmentCompatability10.ts, 2, 14))
|
||||
>obj4 : Symbol(obj4, Decl(assignmentCompatability10.ts, 1, 83))
|
||||
}
|
||||
module __test2__ {
|
||||
>__test2__ : Symbol(__test2__, Decl(assignmentCompatability10.ts, 3, 1))
|
||||
|
||||
export class classWithPublicAndOptional<T,U> { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional<number, string>(1);;
|
||||
>classWithPublicAndOptional : Symbol(classWithPublicAndOptional, Decl(assignmentCompatability10.ts, 4, 18))
|
||||
>T : Symbol(T, Decl(assignmentCompatability10.ts, 5, 44))
|
||||
>U : Symbol(U, Decl(assignmentCompatability10.ts, 5, 46))
|
||||
>one : Symbol(classWithPublicAndOptional.one, Decl(assignmentCompatability10.ts, 5, 63))
|
||||
>T : Symbol(T, Decl(assignmentCompatability10.ts, 5, 44))
|
||||
>two : Symbol(classWithPublicAndOptional.two, Decl(assignmentCompatability10.ts, 5, 77))
|
||||
>U : Symbol(U, Decl(assignmentCompatability10.ts, 5, 46))
|
||||
>x4 : Symbol(x4, Decl(assignmentCompatability10.ts, 5, 104))
|
||||
>classWithPublicAndOptional : Symbol(classWithPublicAndOptional, Decl(assignmentCompatability10.ts, 4, 18))
|
||||
|
||||
export var __val__x4 = x4;
|
||||
>__val__x4 : Symbol(__val__x4, Decl(assignmentCompatability10.ts, 6, 14))
|
||||
>x4 : Symbol(x4, Decl(assignmentCompatability10.ts, 5, 104))
|
||||
}
|
||||
__test2__.__val__x4 = __test1__.__val__obj4
|
||||
>__test2__.__val__x4 : Symbol(__test2__.__val__x4, Decl(assignmentCompatability10.ts, 6, 14))
|
||||
>__test2__ : Symbol(__test2__, Decl(assignmentCompatability10.ts, 3, 1))
|
||||
>__val__x4 : Symbol(__test2__.__val__x4, Decl(assignmentCompatability10.ts, 6, 14))
|
||||
>__test1__.__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability10.ts, 2, 14))
|
||||
>__test1__ : Symbol(__test1__, Decl(assignmentCompatability10.ts, 0, 0))
|
||||
>__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability10.ts, 2, 14))
|
||||
|
51
tests/baselines/reference/assignmentCompatability10.types
Normal file
51
tests/baselines/reference/assignmentCompatability10.types
Normal file
|
@ -0,0 +1,51 @@
|
|||
=== tests/cases/compiler/assignmentCompatability10.ts ===
|
||||
module __test1__ {
|
||||
>__test1__ : typeof __test1__
|
||||
|
||||
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>T : T
|
||||
>U : U
|
||||
>one : T
|
||||
>T : T
|
||||
>two : U
|
||||
>U : U
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
|
||||
>{ one: 1 } : { one: number; }
|
||||
>one : number
|
||||
>1 : number
|
||||
|
||||
export var __val__obj4 = obj4;
|
||||
>__val__obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
>obj4 : interfaceWithPublicAndOptional<number, string>
|
||||
}
|
||||
module __test2__ {
|
||||
>__test2__ : typeof __test2__
|
||||
|
||||
export class classWithPublicAndOptional<T,U> { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional<number, string>(1);;
|
||||
>classWithPublicAndOptional : classWithPublicAndOptional<T, U>
|
||||
>T : T
|
||||
>U : U
|
||||
>one : T
|
||||
>T : T
|
||||
>two : U
|
||||
>U : U
|
||||
>x4 : classWithPublicAndOptional<number, string>
|
||||
>new classWithPublicAndOptional<number, string>(1) : classWithPublicAndOptional<number, string>
|
||||
>classWithPublicAndOptional : typeof classWithPublicAndOptional
|
||||
>1 : number
|
||||
|
||||
export var __val__x4 = x4;
|
||||
>__val__x4 : classWithPublicAndOptional<number, string>
|
||||
>x4 : classWithPublicAndOptional<number, string>
|
||||
}
|
||||
__test2__.__val__x4 = __test1__.__val__obj4
|
||||
>__test2__.__val__x4 = __test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
|
||||
>__test2__.__val__x4 : __test2__.classWithPublicAndOptional<number, string>
|
||||
>__test2__ : typeof __test2__
|
||||
>__val__x4 : __test2__.classWithPublicAndOptional<number, string>
|
||||
>__test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
|
||||
>__test1__ : typeof __test1__
|
||||
>__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
32
tests/baselines/reference/optionalParameterProperty.js
Normal file
32
tests/baselines/reference/optionalParameterProperty.js
Normal 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));
|
|
@ -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; }'.
|
|
@ -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
|
||||
|
|
11
tests/cases/compiler/optionalParameterProperty.ts
Normal file
11
tests/cases/compiler/optionalParameterProperty.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// @strictNullChecks: true
|
||||
|
||||
class C {
|
||||
p: number;
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
constructor(public p?: number) {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Reference in a new issue