mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-12 01:48:33 -05:00
Allow references to uninitialized ambient properties (#36112)
Previously these were incorrectly treated just like normal properties:
```ts
class Parent {
a: any;
constructor(arg: any) {
this.a = arg;
}
}
class Child extends Parent {
declare a: number;
constructor(arg: number) {
super(arg);
console.log(this.a); // Property 'a' is used before being assigned. (2565)
}
}
```
Fixes #35327
This commit is contained in:
committed by
GitHub
parent
357f715382
commit
13cddae3f7
@@ -23298,7 +23298,7 @@ namespace ts {
|
||||
const declaration = prop && prop.valueDeclaration;
|
||||
if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
|
||||
const flowContainer = getControlFlowContainer(node);
|
||||
if (flowContainer.kind === SyntaxKind.Constructor && flowContainer.parent === declaration.parent) {
|
||||
if (flowContainer.kind === SyntaxKind.Constructor && flowContainer.parent === declaration.parent && !(declaration.flags & NodeFlags.Ambient)) {
|
||||
assumeUninitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,4 +85,19 @@ tests/cases/conformance/classes/propertyMemberDeclarations/derivedUninitializedP
|
||||
q!: 1 | 2 | 3 // ok, extends a property from an interface
|
||||
r!: 4 | 5 // error, from class
|
||||
}
|
||||
|
||||
// #35327
|
||||
class L {
|
||||
a: any;
|
||||
constructor(arg: any) {
|
||||
this.a = arg;
|
||||
}
|
||||
}
|
||||
class M extends L {
|
||||
declare a: number;
|
||||
constructor(arg: number) {
|
||||
super(arg);
|
||||
console.log(this.a); // should be OK, M.a is ambient
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,21 @@ class K extends J {
|
||||
q!: 1 | 2 | 3 // ok, extends a property from an interface
|
||||
r!: 4 | 5 // error, from class
|
||||
}
|
||||
|
||||
// #35327
|
||||
class L {
|
||||
a: any;
|
||||
constructor(arg: any) {
|
||||
this.a = arg;
|
||||
}
|
||||
}
|
||||
class M extends L {
|
||||
declare a: number;
|
||||
constructor(arg: number) {
|
||||
super(arg);
|
||||
console.log(this.a); // should be OK, M.a is ambient
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [derivedUninitializedPropertyDeclaration.js]
|
||||
@@ -178,3 +193,19 @@ var K = /** @class */ (function (_super) {
|
||||
}
|
||||
return K;
|
||||
}(J));
|
||||
// #35327
|
||||
var L = /** @class */ (function () {
|
||||
function L(arg) {
|
||||
this.a = arg;
|
||||
}
|
||||
return L;
|
||||
}());
|
||||
var M = /** @class */ (function (_super) {
|
||||
__extends(M, _super);
|
||||
function M(arg) {
|
||||
var _this = _super.call(this, arg) || this;
|
||||
console.log(_this.a); // should be OK, M.a is ambient
|
||||
return _this;
|
||||
}
|
||||
return M;
|
||||
}(L));
|
||||
|
||||
@@ -147,3 +147,44 @@ class K extends J {
|
||||
>r : Symbol(K.r, Decl(derivedUninitializedPropertyDeclaration.ts, 63, 17))
|
||||
}
|
||||
|
||||
// #35327
|
||||
class L {
|
||||
>L : Symbol(L, Decl(derivedUninitializedPropertyDeclaration.ts, 65, 1))
|
||||
|
||||
a: any;
|
||||
>a : Symbol(L.a, Decl(derivedUninitializedPropertyDeclaration.ts, 68, 9))
|
||||
|
||||
constructor(arg: any) {
|
||||
>arg : Symbol(arg, Decl(derivedUninitializedPropertyDeclaration.ts, 70, 16))
|
||||
|
||||
this.a = arg;
|
||||
>this.a : Symbol(L.a, Decl(derivedUninitializedPropertyDeclaration.ts, 68, 9))
|
||||
>this : Symbol(L, Decl(derivedUninitializedPropertyDeclaration.ts, 65, 1))
|
||||
>a : Symbol(L.a, Decl(derivedUninitializedPropertyDeclaration.ts, 68, 9))
|
||||
>arg : Symbol(arg, Decl(derivedUninitializedPropertyDeclaration.ts, 70, 16))
|
||||
}
|
||||
}
|
||||
class M extends L {
|
||||
>M : Symbol(M, Decl(derivedUninitializedPropertyDeclaration.ts, 73, 1))
|
||||
>L : Symbol(L, Decl(derivedUninitializedPropertyDeclaration.ts, 65, 1))
|
||||
|
||||
declare a: number;
|
||||
>a : Symbol(M.a, Decl(derivedUninitializedPropertyDeclaration.ts, 74, 19))
|
||||
|
||||
constructor(arg: number) {
|
||||
>arg : Symbol(arg, Decl(derivedUninitializedPropertyDeclaration.ts, 76, 16))
|
||||
|
||||
super(arg);
|
||||
>super : Symbol(L, Decl(derivedUninitializedPropertyDeclaration.ts, 65, 1))
|
||||
>arg : Symbol(arg, Decl(derivedUninitializedPropertyDeclaration.ts, 76, 16))
|
||||
|
||||
console.log(this.a); // should be OK, M.a is ambient
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.a : Symbol(M.a, Decl(derivedUninitializedPropertyDeclaration.ts, 74, 19))
|
||||
>this : Symbol(M, Decl(derivedUninitializedPropertyDeclaration.ts, 73, 1))
|
||||
>a : Symbol(M.a, Decl(derivedUninitializedPropertyDeclaration.ts, 74, 19))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,3 +150,47 @@ class K extends J {
|
||||
>r : 5 | 4
|
||||
}
|
||||
|
||||
// #35327
|
||||
class L {
|
||||
>L : L
|
||||
|
||||
a: any;
|
||||
>a : any
|
||||
|
||||
constructor(arg: any) {
|
||||
>arg : any
|
||||
|
||||
this.a = arg;
|
||||
>this.a = arg : any
|
||||
>this.a : any
|
||||
>this : this
|
||||
>a : any
|
||||
>arg : any
|
||||
}
|
||||
}
|
||||
class M extends L {
|
||||
>M : M
|
||||
>L : L
|
||||
|
||||
declare a: number;
|
||||
>a : number
|
||||
|
||||
constructor(arg: number) {
|
||||
>arg : number
|
||||
|
||||
super(arg);
|
||||
>super(arg) : void
|
||||
>super : typeof L
|
||||
>arg : number
|
||||
|
||||
console.log(this.a); // should be OK, M.a is ambient
|
||||
>console.log(this.a) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,3 +65,18 @@ class K extends J {
|
||||
q!: 1 | 2 | 3 // ok, extends a property from an interface
|
||||
r!: 4 | 5 // error, from class
|
||||
}
|
||||
|
||||
// #35327
|
||||
class L {
|
||||
a: any;
|
||||
constructor(arg: any) {
|
||||
this.a = arg;
|
||||
}
|
||||
}
|
||||
class M extends L {
|
||||
declare a: number;
|
||||
constructor(arg: number) {
|
||||
super(arg);
|
||||
console.log(this.a); // should be OK, M.a is ambient
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user