diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8b57947438273..ca4de71da1759 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13317,13 +13317,13 @@ namespace ts { .expression; // x const classSymbol = checkExpression(className).symbol; if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { - return getInferredClassType(classSymbol); + return getFlowTypeOfReference(node, getInferredClassType(classSymbol)); } } const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { - return thisType; + return getFlowTypeOfReference(node, thisType); } } @@ -13336,7 +13336,7 @@ namespace ts { if (isInJavaScriptFile(node)) { const type = getTypeForThisExpressionFromJSDoc(container); if (type && type !== unknownType) { - return type; + return getFlowTypeOfReference(node, type); } } } diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js new file mode 100644 index 0000000000000..14edf1abca65a --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.js @@ -0,0 +1,26 @@ +//// [controlFlowAnalysisOnBareThisKeyword.ts] +declare function isBig(x: any): x is { big: true }; +function bigger(this: {}) { + if (isBig(this)) { + this.big; // Expect property to exist + } +} + +function bar(this: string | number) { + if (typeof this === "string") { + const x: string = this; + } +} + +//// [controlFlowAnalysisOnBareThisKeyword.js] +"use strict"; +function bigger() { + if (isBig(this)) { + this.big; // Expect property to exist + } +} +function bar() { + if (typeof this === "string") { + var x = this; + } +} diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols new file mode 100644 index 0000000000000..f15dd5955d72e --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts === +declare function isBig(x: any): x is { big: true }; +>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0)) +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23)) +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23)) +>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) + +function bigger(this: {}) { +>bigger : Symbol(bigger, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 51)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) + + if (isBig(this)) { +>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) + + this.big; // Expect property to exist +>this.big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16)) +>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38)) + } +} + +function bar(this: string | number) { +>bar : Symbol(bar, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 5, 1)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + + if (typeof this === "string") { +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + + const x: string = this; +>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 9, 13)) +>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13)) + } +} diff --git a/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types new file mode 100644 index 0000000000000..f44dd8ee68521 --- /dev/null +++ b/tests/baselines/reference/controlFlowAnalysisOnBareThisKeyword.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts === +declare function isBig(x: any): x is { big: true }; +>isBig : (x: any) => x is { big: true; } +>x : any +>x : any +>big : true +>true : true + +function bigger(this: {}) { +>bigger : (this: {}) => void +>this : {} + + if (isBig(this)) { +>isBig(this) : boolean +>isBig : (x: any) => x is { big: true; } +>this : {} + + this.big; // Expect property to exist +>this.big : true +>this : { big: true; } +>big : true + } +} + +function bar(this: string | number) { +>bar : (this: string | number) => void +>this : string | number + + if (typeof this === "string") { +>typeof this === "string" : boolean +>typeof this : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>this : string | number +>"string" : "string" + + const x: string = this; +>x : string +>this : string + } +} diff --git a/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts b/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts new file mode 100644 index 0000000000000..6ecf297a7c2fe --- /dev/null +++ b/tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts @@ -0,0 +1,13 @@ +// @strict: true +declare function isBig(x: any): x is { big: true }; +function bigger(this: {}) { + if (isBig(this)) { + this.big; // Expect property to exist + } +} + +function bar(this: string | number) { + if (typeof this === "string") { + const x: string = this; + } +} \ No newline at end of file