From 4378441e0c286feae133c13059ba47f5dc7d5bfe Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 4 Jan 2023 22:05:19 +0200 Subject: [PATCH] fix(51198): The 'this' context of type 'T' is not assignable to method's 'this' of type 'this' (#51216) * fix(51198): skip checking this context of type assignable to super * update comment --- src/compiler/checker.ts | 5 ++--- .../thisTypeInFunctionsNegative.errors.txt | 6 ++++++ .../reference/thisTypeInFunctionsNegative.js | 11 +++++++++++ .../thisTypeInFunctionsNegative.symbols | 15 +++++++++++++++ .../reference/thisTypeInFunctionsNegative.types | 16 ++++++++++++++++ .../thisType/thisTypeInFunctionsNegative.ts | 6 ++++++ 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4c1ad31d43ff6..30eb32a7ac48a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31890,7 +31890,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, ): readonly Diagnostic[] | undefined { - const errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } = { errors: undefined, skipLogging: true }; if (isJsxOpeningLikeElement(node)) { if (!checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) { @@ -31900,10 +31899,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } const thisType = getThisTypeOfSignature(signature); - if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { + if (thisType && thisType !== voidType && !(isNewExpression(node) || isCallExpression(node) && isSuperProperty(node.expression))) { // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible. - // If the expression is a new expression, then the check is skipped. + // If the expression is a new expression or super call expression, then the check is skipped. const thisArgumentNode = getThisArgumentOfCall(node); const thisArgumentType = getThisArgumentType(thisArgumentNode); const errorNode = reportErrors ? (thisArgumentNode || node) : undefined; diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt index a3a3efafaa6e2..0c9dd0264d248 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt @@ -439,4 +439,10 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(178,22): e const f4 = async (this: {n: number}, m: number) => m + this.n; ~~~~~~~~~~~~~~~~~ !!! error TS2730: An arrow function cannot have a 'this' parameter. + + class Derived3 extends Base2 { + f(this: this) { + super.polymorphic(); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.js b/tests/baselines/reference/thisTypeInFunctionsNegative.js index a3fe0b8ee5940..4c5df4a764867 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.js +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.js @@ -177,6 +177,12 @@ c.explicitProperty = (this, m) => m + this.n; const f2 = (this: {n: number}, m: number) => m + this.n; const f3 = async (this: {n: number}, m: number) => m + this.n; const f4 = async (this: {n: number}, m: number) => m + this.n; + +class Derived3 extends Base2 { + f(this: this) { + super.polymorphic(); + } +} //// [thisTypeInFunctionsNegative.js] @@ -332,3 +338,8 @@ c.explicitProperty = (m) => m + this.n; const f2 = (m) => m + this.n; const f3 = (m) => __awaiter(this, void 0, void 0, function* () { return m + this.n; }); const f4 = (m) => __awaiter(this, void 0, void 0, function* () { return m + this.n; }); +class Derived3 extends Base2 { + f() { + super.polymorphic(); + } +} diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.symbols b/tests/baselines/reference/thisTypeInFunctionsNegative.symbols index 77b4b6a15a700..d275ba895574b 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.symbols +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.symbols @@ -696,3 +696,18 @@ const f4 = async (this: {n: number}, m: number) => m + this.n; >m : Symbol(m, Decl(thisTypeInFunctionsNegative.ts, 177, 39)) >this : Symbol(globalThis) +class Derived3 extends Base2 { +>Derived3 : Symbol(Derived3, Decl(thisTypeInFunctionsNegative.ts, 177, 65)) +>Base2 : Symbol(Base2, Decl(thisTypeInFunctionsNegative.ts, 128, 1)) + + f(this: this) { +>f : Symbol(Derived3.f, Decl(thisTypeInFunctionsNegative.ts, 179, 30)) +>this : Symbol(this, Decl(thisTypeInFunctionsNegative.ts, 180, 6)) + + super.polymorphic(); +>super.polymorphic : Symbol(Base2.polymorphic, Decl(thisTypeInFunctionsNegative.ts, 130, 13)) +>super : Symbol(Base2, Decl(thisTypeInFunctionsNegative.ts, 128, 1)) +>polymorphic : Symbol(Base2.polymorphic, Decl(thisTypeInFunctionsNegative.ts, 130, 13)) + } +} + diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.types b/tests/baselines/reference/thisTypeInFunctionsNegative.types index 36837e3108934..6a3d134f34772 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.types +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.types @@ -804,3 +804,19 @@ const f4 = async (this: {n: number}, m: number) => m + this.n; >this : typeof globalThis >n : any +class Derived3 extends Base2 { +>Derived3 : Derived3 +>Base2 : Base2 + + f(this: this) { +>f : (this: this) => void +>this : this + + super.polymorphic(); +>super.polymorphic() : number +>super.polymorphic : (this: this) => number +>super : Base2 +>polymorphic : (this: this) => number + } +} + diff --git a/tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts b/tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts index 217fbb9362283..20f59cbfe02a4 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts @@ -178,3 +178,9 @@ c.explicitProperty = (this, m) => m + this.n; const f2 = (this: {n: number}, m: number) => m + this.n; const f3 = async (this: {n: number}, m: number) => m + this.n; const f4 = async (this: {n: number}, m: number) => m + this.n; + +class Derived3 extends Base2 { + f(this: this) { + super.polymorphic(); + } +}