From fa598758b12d9b06c2b21579e8512a32bffd5065 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 8 Feb 2016 09:41:57 -0800 Subject: [PATCH] Improve display and contextual typing of `this` 1. Always display `this` type if annotated. 2. Contextually type un-annotated `this` parameters in addition to `this` expressions. --- src/compiler/checker.ts | 9 +- .../reference/contextualTyping24.errors.txt | 4 +- .../looseThisTypeInFunctions.errors.txt | 4 +- .../reference/thisTypeInFunctions.types | 128 +++++++++--------- .../thisTypeInFunctionsNegative.errors.txt | 16 +-- tests/cases/fourslash/quickInfoOnThis.ts | 16 ++- 6 files changed, 92 insertions(+), 85 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index be98dc985b5..06986107fbb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2203,15 +2203,14 @@ namespace ts { function buildDisplayForParametersAndDelimiters(thisType: Type, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { writePunctuation(writer, SyntaxKind.OpenParenToken); - const useThisType = thisType && thisType.symbol; - if (useThisType) { + if (thisType) { writeKeyword(writer, SyntaxKind.ThisKeyword); writePunctuation(writer, SyntaxKind.ColonToken); writeSpace(writer); buildTypeDisplay(thisType, writer, enclosingDeclaration, flags, symbolStack); } for (let i = 0; i < parameters.length; i++) { - if (i > 0 || useThisType) { + if (i > 0 || thisType) { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); } @@ -2690,7 +2689,9 @@ namespace ts { } } // Use contextual parameter type if one is available - const type = getContextuallyTypedParameterType(declaration); + const type = declaration.symbol.name === "this" + ? getContextuallyTypedThisType(func) + : getContextuallyTypedParameterType(declaration); if (type) { return type; } diff --git a/tests/baselines/reference/contextualTyping24.errors.txt b/tests/baselines/reference/contextualTyping24.errors.txt index b4d0d534456..d5cb13e4e3e 100644 --- a/tests/baselines/reference/contextualTyping24.errors.txt +++ b/tests/baselines/reference/contextualTyping24.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/contextualTyping24.ts(1,55): error TS2322: Type '(a: string) => number' is not assignable to type '(a: { (): number; (i: number): number; }) => number'. +tests/cases/compiler/contextualTyping24.ts(1,55): error TS2322: Type '(this: void, a: string) => number' is not assignable to type '(a: { (): number; (i: number): number; }) => number'. Types of parameters 'a' and 'a' are incompatible. Type 'string' is not assignable to type '{ (): number; (i: number): number; }'. @@ -6,6 +6,6 @@ tests/cases/compiler/contextualTyping24.ts(1,55): error TS2322: Type '(a: string ==== tests/cases/compiler/contextualTyping24.ts (1 errors) ==== var foo:(a:{():number; (i:number):number; })=>number; foo = function(this: void, a:string){return 5}; ~~~ -!!! error TS2322: Type '(a: string) => number' is not assignable to type '(a: { (): number; (i: number): number; }) => number'. +!!! error TS2322: Type '(this: void, a: string) => number' is not assignable to type '(a: { (): number; (i: number): number; }) => number'. !!! error TS2322: Types of parameters 'a' and 'a' are incompatible. !!! error TS2322: Type 'string' is not assignable to type '{ (): number; (i: number): number; }'. \ No newline at end of file diff --git a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt index 317446050a8..4eef7d83f78 100644 --- a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt +++ b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(m: number) => number'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'. Types of parameters 'this' and 'this' are incompatible. Type 'void' is not assignable to type 'C'. tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(32,5): error TS1005: ',' expected. @@ -30,7 +30,7 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,19): error let c = new C(); c.explicitVoid = c.explicitThis; // error, 'void' is missing everything ~~~~~~~~~~~~~~ -!!! error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(m: number) => number'. +!!! error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'. !!! error TS2322: Types of parameters 'this' and 'this' are incompatible. !!! error TS2322: Type 'void' is not assignable to type 'C'. let o = { diff --git a/tests/baselines/reference/thisTypeInFunctions.types b/tests/baselines/reference/thisTypeInFunctions.types index e1044bb3d90..2c334b2caed 100644 --- a/tests/baselines/reference/thisTypeInFunctions.types +++ b/tests/baselines/reference/thisTypeInFunctions.types @@ -56,7 +56,7 @@ class C { >m : number } explicitVoid(this: void, m: number): number { ->explicitVoid : (m: number) => number +>explicitVoid : (this: void, m: number) => number >this : void >m : number @@ -83,11 +83,11 @@ interface I { >a : number explicitVoid1(this: void): number; ->explicitVoid1 : () => number +>explicitVoid1 : (this: void) => number >this : void explicitVoid2(this: void): number; ->explicitVoid2 : () => number +>explicitVoid2 : (this: void) => number >this : void explicitStructural(this: {a: number}): number; @@ -108,7 +108,7 @@ interface I { >implicitMethod : (this: this) => number implicitFunction: () => number; ->implicitFunction : () => number +>implicitFunction : (this: void) => number } function explicitStructural(this: { y: number }, x: number): number { >explicitStructural : (this: { y: number; }, x: number) => number @@ -134,7 +134,7 @@ function justThis(this: { y: number }): number { >y : number } function implicitThis(n: number): number { ->implicitThis : (n: number) => number +>implicitThis : (this: void, n: number) => number >n : number return 12; @@ -204,37 +204,37 @@ let impl: I = { >a : any } impl.explicitVoid1 = function () { return 12; }; ->impl.explicitVoid1 = function () { return 12; } : () => number ->impl.explicitVoid1 : () => number +>impl.explicitVoid1 = function () { return 12; } : (this: void) => number +>impl.explicitVoid1 : (this: void) => number >impl : I ->explicitVoid1 : () => number ->function () { return 12; } : () => number +>explicitVoid1 : (this: void) => number +>function () { return 12; } : (this: void) => number >12 : number impl.explicitVoid2 = () => 12; >impl.explicitVoid2 = () => 12 : () => number ->impl.explicitVoid2 : () => number +>impl.explicitVoid2 : (this: void) => number >impl : I ->explicitVoid2 : () => number +>explicitVoid2 : (this: void) => number >() => 12 : () => number >12 : number impl.explicitStructural = function() { return this.a; }; ->impl.explicitStructural = function() { return this.a; } : () => number +>impl.explicitStructural = function() { return this.a; } : (this: void) => number >impl.explicitStructural : (this: { a: number; }) => number >impl : I >explicitStructural : (this: { a: number; }) => number ->function() { return this.a; } : () => number +>function() { return this.a; } : (this: void) => number >this.a : number >this : { a: number; } >a : number impl.explicitInterface = function() { return this.a; }; ->impl.explicitInterface = function() { return this.a; } : () => number +>impl.explicitInterface = function() { return this.a; } : (this: void) => number >impl.explicitInterface : (this: I) => number >impl : I >explicitInterface : (this: I) => number ->function() { return this.a; } : () => number +>function() { return this.a; } : (this: void) => number >this.a : number >this : I >a : number @@ -256,21 +256,21 @@ impl.explicitInterface = () => 12; >12 : number impl.explicitThis = function () { return this.a; }; ->impl.explicitThis = function () { return this.a; } : () => number +>impl.explicitThis = function () { return this.a; } : (this: void) => number >impl.explicitThis : (this: I) => number >impl : I >explicitThis : (this: I) => number ->function () { return this.a; } : () => number +>function () { return this.a; } : (this: void) => number >this.a : number >this : I >a : number impl.implicitMethod = function () { return this.a; }; ->impl.implicitMethod = function () { return this.a; } : () => number +>impl.implicitMethod = function () { return this.a; } : (this: void) => number >impl.implicitMethod : (this: I) => number >impl : I >implicitMethod : (this: I) => number ->function () { return this.a; } : () => number +>function () { return this.a; } : (this: void) => number >this.a : number >this : I >a : number @@ -285,9 +285,9 @@ impl.implicitMethod = () => 12; impl.implicitFunction = () => this.a; // ok, this: any because it refers to some outer object (window?) >impl.implicitFunction = () => this.a : () => any ->impl.implicitFunction : () => number +>impl.implicitFunction : (this: void) => number >impl : I ->implicitFunction : () => number +>implicitFunction : (this: void) => number >() => this.a : () => any >this.a : any >this : any @@ -308,15 +308,15 @@ let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, f: >explicitStructural : (this: { y: number; }, x: number) => number let implicitAnyOk: {notSpecified: number, f: (x: number) => number} = { notSpecified: 12, f: implicitThis }; ->implicitAnyOk : { notSpecified: number; f: (x: number) => number; } +>implicitAnyOk : { notSpecified: number; f: (this: void, x: number) => number; } >notSpecified : number ->f : (x: number) => number +>f : (this: void, x: number) => number >x : number ->{ notSpecified: 12, f: implicitThis } : { notSpecified: number; f: (n: number) => number; } +>{ notSpecified: 12, f: implicitThis } : { notSpecified: number; f: (this: void, n: number) => number; } >notSpecified : number >12 : number ->f : (n: number) => number ->implicitThis : (n: number) => number +>f : (this: void, n: number) => number +>implicitThis : (this: void, n: number) => number ok.f(13); >ok.f(13) : number @@ -327,14 +327,14 @@ ok.f(13); implicitThis(12); >implicitThis(12) : number ->implicitThis : (n: number) => number +>implicitThis : (this: void, n: number) => number >12 : number implicitAnyOk.f(12); >implicitAnyOk.f(12) : number ->implicitAnyOk.f : (x: number) => number ->implicitAnyOk : { notSpecified: number; f: (x: number) => number; } ->f : (x: number) => number +>implicitAnyOk.f : (this: void, x: number) => number +>implicitAnyOk : { notSpecified: number; f: (this: void, x: number) => number; } +>f : (this: void, x: number) => number >12 : number let c = new C(); @@ -410,7 +410,7 @@ d.implicitThis(12); >12 : number let reconstructed: { ->reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(m: number): number; } +>reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(this: void, m: number): number; } n: number, >n : number @@ -438,12 +438,12 @@ let reconstructed: { >m : number explicitVoid(this: void, m: number): number, ->explicitVoid : (m: number) => number +>explicitVoid : (this: void, m: number) => number >this : void >m : number } = { ->{ n: 12, explicitThis: c.explicitThis, implicitThis: c.implicitThis, explicitC: c.explicitC, explicitProperty: c.explicitProperty, explicitVoid: c.explicitVoid} : { n: number; explicitThis: (this: C, m: number) => number; implicitThis: (this: C, m: number) => number; explicitC: (this: C, m: number) => number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid: (m: number) => number; } +>{ n: 12, explicitThis: c.explicitThis, implicitThis: c.implicitThis, explicitC: c.explicitC, explicitProperty: c.explicitProperty, explicitVoid: c.explicitVoid} : { n: number; explicitThis: (this: C, m: number) => number; implicitThis: (this: C, m: number) => number; explicitC: (this: C, m: number) => number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid: (this: void, m: number) => number; } n: 12, >n : number @@ -474,23 +474,23 @@ let reconstructed: { >explicitProperty : (this: { n: number; }, m: number) => number explicitVoid: c.explicitVoid ->explicitVoid : (m: number) => number ->c.explicitVoid : (m: number) => number +>explicitVoid : (this: void, m: number) => number +>c.explicitVoid : (this: void, m: number) => number >c : C ->explicitVoid : (m: number) => number +>explicitVoid : (this: void, m: number) => number }; reconstructed.explicitProperty(11); >reconstructed.explicitProperty(11) : number >reconstructed.explicitProperty : (this: { n: number; }, m: number) => number ->reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(m: number): number; } +>reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(this: void, m: number): number; } >explicitProperty : (this: { n: number; }, m: number) => number >11 : number reconstructed.implicitThis(11); >reconstructed.implicitThis(11) : number >reconstructed.implicitThis : (m: number) => number ->reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(m: number): number; } +>reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(this: void, m: number): number; } >implicitThis : (m: number) => number >11 : number @@ -520,14 +520,14 @@ let anyToSpecified: (this: { y: number }, x: number) => number = function(x: num >this : { y: number; } >y : number >x : number ->function(x: number): number { return x + 12; } : (x: number) => number +>function(x: number): number { return x + 12; } : (this: void, x: number) => number >x : number >x + 12 : number >x : number >12 : number let unspecifiedLambda: (x: number) => number = x => x + 12; ->unspecifiedLambda : (x: number) => number +>unspecifiedLambda : (this: void, x: number) => number >x : number >x => x + 12 : (x: number) => number >x : number @@ -536,7 +536,7 @@ let unspecifiedLambda: (x: number) => number = x => x + 12; >12 : number let specifiedLambda: (this: void, x: number) => number = x => x + 12; ->specifiedLambda : (x: number) => number +>specifiedLambda : (this: void, x: number) => number >this : void >x : number >x => x + 12 : (x: number) => number @@ -550,14 +550,14 @@ let unspecifiedLambdaToSpecified: (this: {y: number}, x: number) => number = uns >this : { y: number; } >y : number >x : number ->unspecifiedLambda : (x: number) => number +>unspecifiedLambda : (this: void, x: number) => number let specifiedLambdaToSpecified: (this: {y: number}, x: number) => number = specifiedLambda; >specifiedLambdaToSpecified : (this: { y: number; }, x: number) => number >this : { y: number; } >y : number >x : number ->specifiedLambda : (x: number) => number +>specifiedLambda : (this: void, x: number) => number let explicitCFunction: (this: C, m: number) => number; @@ -622,7 +622,7 @@ c.explicitProperty = reconstructed.explicitProperty; >c : C >explicitProperty : (this: { n: number; }, m: number) => number >reconstructed.explicitProperty : (this: { n: number; }, m: number) => number ->reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(m: number): number; } +>reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(this: void, m: number): number; } >explicitProperty : (this: { n: number; }, m: number) => number // lambdas are assignable to anything @@ -719,11 +719,11 @@ c.explicitThis = function(this: C, m: number) { return this.n + m }; // this:any compatibility c.explicitC = function(m) { return this.n + m }; ->c.explicitC = function(m) { return this.n + m } : (m: number) => number +>c.explicitC = function(m) { return this.n + m } : (this: void, m: number) => number >c.explicitC : (this: C, m: number) => number >c : C >explicitC : (this: C, m: number) => number ->function(m) { return this.n + m } : (m: number) => number +>function(m) { return this.n + m } : (this: void, m: number) => number >m : number >this.n + m : number >this.n : number @@ -732,11 +732,11 @@ c.explicitC = function(m) { return this.n + m }; >m : number c.explicitProperty = function(m) { return this.n + m }; ->c.explicitProperty = function(m) { return this.n + m } : (m: number) => number +>c.explicitProperty = function(m) { return this.n + m } : (this: void, m: number) => number >c.explicitProperty : (this: { n: number; }, m: number) => number >c : C >explicitProperty : (this: { n: number; }, m: number) => number ->function(m) { return this.n + m } : (m: number) => number +>function(m) { return this.n + m } : (this: void, m: number) => number >m : number >this.n + m : number >this.n : number @@ -745,11 +745,11 @@ c.explicitProperty = function(m) { return this.n + m }; >m : number c.explicitThis = function(m) { return this.n + m }; ->c.explicitThis = function(m) { return this.n + m } : (m: number) => number +>c.explicitThis = function(m) { return this.n + m } : (this: void, m: number) => number >c.explicitThis : (this: C, m: number) => number >c : C >explicitThis : (this: C, m: number) => number ->function(m) { return this.n + m } : (m: number) => number +>function(m) { return this.n + m } : (this: void, m: number) => number >m : number >this.n + m : number >this.n : number @@ -758,11 +758,11 @@ c.explicitThis = function(m) { return this.n + m }; >m : number c.implicitThis = function(m) { return this.n + m }; ->c.implicitThis = function(m) { return this.n + m } : (m: number) => number +>c.implicitThis = function(m) { return this.n + m } : (this: void, m: number) => number >c.implicitThis : (this: C, m: number) => number >c : C >implicitThis : (this: C, m: number) => number ->function(m) { return this.n + m } : (m: number) => number +>function(m) { return this.n + m } : (this: void, m: number) => number >m : number >this.n + m : number >this.n : number @@ -776,7 +776,7 @@ c.implicitThis = reconstructed.implicitThis; >c : C >implicitThis : (this: C, m: number) => number >reconstructed.implicitThis : (m: number) => number ->reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(m: number): number; } +>reconstructed : { n: number; explicitThis(this: C, m: number): number; implicitThis(m: number): number; explicitC(this: C, m: number): number; explicitProperty: (this: { n: number; }, m: number) => number; explicitVoid(this: void, m: number): number; } >implicitThis : (m: number) => number c.explicitC = function(this: B, m: number) { return this.n + m }; @@ -797,9 +797,9 @@ c.explicitC = function(this: B, m: number) { return this.n + m }; // this:void compatibility c.explicitVoid = n => n; >c.explicitVoid = n => n : (n: number) => number ->c.explicitVoid : (m: number) => number +>c.explicitVoid : (this: void, m: number) => number >c : C ->explicitVoid : (m: number) => number +>explicitVoid : (this: void, m: number) => number >n => n : (n: number) => number >n : number >n : number @@ -978,7 +978,7 @@ function LiteralTypeThis(this: {x: string}) { >"ok" : string } function AnyThis(this: any) { ->AnyThis : () => void +>AnyThis : (this: any) => void >this : any this.x = "ok"; @@ -1001,20 +1001,20 @@ let literalTypeThis = new LiteralTypeThis(); let anyThis = new AnyThis(); >anyThis : any >new AnyThis() : any ->AnyThis : () => void +>AnyThis : (this: any) => void //// type parameter inference //// declare var f: { ->f : { (x: number): number; call(this: (...argArray: any[]) => U, ...argArray: any[]): U; } +>f : { (this: void, x: number): number; call(this: (this: void, ...argArray: any[]) => U, ...argArray: any[]): U; } (this: void, x: number): number, >this : void >x : number call(this: (...argArray: any[]) => U, ...argArray: any[]): U; ->call : (this: (...argArray: any[]) => U, ...argArray: any[]) => U +>call : (this: (this: void, ...argArray: any[]) => U, ...argArray: any[]) => U >U : U ->this : (...argArray: any[]) => U +>this : (this: void, ...argArray: any[]) => U >argArray : any[] >U : U >argArray : any[] @@ -1024,13 +1024,13 @@ declare var f: { let n: number = f.call(12); >n : number >f.call(12) : number ->f.call : (this: (...argArray: any[]) => U, ...argArray: any[]) => U ->f : { (x: number): number; call(this: (...argArray: any[]) => U, ...argArray: any[]): U; } ->call : (this: (...argArray: any[]) => U, ...argArray: any[]) => U +>f.call : (this: (this: void, ...argArray: any[]) => U, ...argArray: any[]) => U +>f : { (this: void, x: number): number; call(this: (this: void, ...argArray: any[]) => U, ...argArray: any[]): U; } +>call : (this: (this: void, ...argArray: any[]) => U, ...argArray: any[]) => U >12 : number function missingTypeIsImplicitAny(this, a: number) { return a; } ->missingTypeIsImplicitAny : (a: number) => number +>missingTypeIsImplicitAny : (this: any, a: number) => number >this : any >a : number >a : number diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt index 0b755b9e0bd..fdb9489f639 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt @@ -33,7 +33,7 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(95,1): err tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(96,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(97,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(98,1): error TS2346: Supplied parameters do not match any signature of call target. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(101,5): error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(x: number) => number'. +tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(101,5): error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(this: void, x: number) => number'. Types of parameters 'this' and 'this' are incompatible. Type 'void' is not assignable to type '{ y: number; }'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(124,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'. @@ -70,13 +70,13 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(134,1): er Types of parameters 'this' and 'this' are incompatible. Type '{ n: number; }' is not assignable to type 'D'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(135,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(136,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(136,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. Types of parameters 'this' and 'this' are incompatible. Type 'void' is not assignable to type 'D'. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(137,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(137,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. Types of parameters 'this' and 'this' are incompatible. Type 'void' is not assignable to type 'D'. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(138,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(138,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. Types of parameters 'this' and 'this' are incompatible. Type 'void' is not assignable to type 'D'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(146,51): error TS2339: Property 'x' does not exist on type 'typeof Base1'. @@ -287,7 +287,7 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(197,35): e // oops, this triggers contextual typing, which needs to be updated to understand that =>'s `this` is void. let specifiedToImplicitVoid: (x: number) => number = explicitStructural; ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(x: number) => number'. +!!! error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(this: void, x: number) => number'. !!! error TS2322: Types of parameters 'this' and 'this' are incompatible. !!! error TS2322: Type 'void' is not assignable to type '{ y: number; }'. @@ -371,17 +371,17 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(197,35): e !!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'. c.explicitVoid = d.implicitD; ~~~~~~~~~~~~~~ -!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. !!! error TS2322: Types of parameters 'this' and 'this' are incompatible. !!! error TS2322: Type 'void' is not assignable to type 'D'. c.explicitVoid = d.explicitD; ~~~~~~~~~~~~~~ -!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. !!! error TS2322: Types of parameters 'this' and 'this' are incompatible. !!! error TS2322: Type 'void' is not assignable to type 'D'. c.explicitVoid = d.explicitThis; ~~~~~~~~~~~~~~ -!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'. +!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: void, m: number) => number'. !!! error TS2322: Types of parameters 'this' and 'this' are incompatible. !!! error TS2322: Type 'void' is not assignable to type 'D'. diff --git a/tests/cases/fourslash/quickInfoOnThis.ts b/tests/cases/fourslash/quickInfoOnThis.ts index 3213b85174e..57bbb6c5a3e 100644 --- a/tests/cases/fourslash/quickInfoOnThis.ts +++ b/tests/cases/fourslash/quickInfoOnThis.ts @@ -43,16 +43,20 @@ //// console.log(th/*15*/is); ////} //// -//// interface ContextualInterface { +////interface ContextualInterface { //// m: number; //// method(this: this, n: number); -//// } -//// let o: ContextualInterface = { +////} +////let o: ContextualInterface = { //// m: 12, //// method(n) { //// let x = this/*16*/.m; //// } -//// } +////} +////interface ContextualInterface2 { +//// (this: void, n: number): void; +////} +////let contextualInterface2: ContextualInterface2 = function (th/*17*/is, n) { } goTo.marker('1'); verify.quickInfoIs('void'); @@ -87,4 +91,6 @@ goTo.marker('15'); verify.quickInfoIs('this: {\n n: number;\n}'); goTo.marker('16'); -verify.quickInfoIs('this: ContextualInterface'); \ No newline at end of file +verify.quickInfoIs('this: ContextualInterface'); +goTo.marker('17'); +verify.quickInfoIs('(parameter) this: void'); \ No newline at end of file