53a756ea63
* Type `this` in more constructor functions Previously, `this: this` in constructor functions only when there was an explicit `@constructor` tag on the function. Now, `this: this` for any function that's known to be a constructor function. This improves completions inside constructor functions; also note that previously the compiler *did* type `this: this` inside methods of constructor functions, so this fix makes us more consistent. This is reflected in the large number of baselines that improve. The fix is a simple switch to `isJSConstructor`, which is the standard way to detect constructor functions. I'm not sure why the original PR didn't use this method. I remember discussing this limitation in the original bug, #25979, and I guess I decided that it made sense. But I was heavily primed by the bug's framing of the problem in terms of `noImplicitThis`, which *should* require an explicit `@constructor` tag. With better typing comes better detection of `@readonly` assignment; I had to fix the readonly detection code to use `isJSConstructor` as well. * Remove `Add @class tag` fix for noImplicitThis. The new rules mean that it never applies. It's possible that it should apply to functions like ```js function f() { this.init() } ``` In which `init` is never defined, but I think this program is incomplete enough that not offering the fix is fine. * Fix precedence of `@this` Previously, both `@class` and `@this` in a jsdoc would cause the `@this` annotation to be ignored. This became a worse problem with this PR, because `this` is correctly typed even without the annotation. This commit makes sure that `@this` is checked first and used if present.
130 lines
2.2 KiB
Plaintext
130 lines
2.2 KiB
Plaintext
=== tests/cases/conformance/salsa/a.js ===
|
|
function Instance() {
|
|
>Instance : typeof Instance
|
|
|
|
this.i = 'simple'
|
|
>this.i = 'simple' : "simple"
|
|
>this.i : any
|
|
>this : this
|
|
>i : any
|
|
>'simple' : "simple"
|
|
}
|
|
var i = new Instance();
|
|
>i : Instance
|
|
>new Instance() : Instance
|
|
>Instance : typeof Instance
|
|
|
|
Instance;
|
|
>Instance : typeof Instance
|
|
|
|
i;
|
|
>i : Instance
|
|
|
|
function StaticToo() {
|
|
>StaticToo : typeof StaticToo
|
|
|
|
this.i = 'more complex'
|
|
>this.i = 'more complex' : "more complex"
|
|
>this.i : any
|
|
>this : this
|
|
>i : any
|
|
>'more complex' : "more complex"
|
|
}
|
|
StaticToo.property = 'yep'
|
|
>StaticToo.property = 'yep' : "yep"
|
|
>StaticToo.property : string
|
|
>StaticToo : typeof StaticToo
|
|
>property : string
|
|
>'yep' : "yep"
|
|
|
|
var s = new StaticToo();
|
|
>s : StaticToo
|
|
>new StaticToo() : StaticToo
|
|
>StaticToo : typeof StaticToo
|
|
|
|
s;
|
|
>s : StaticToo
|
|
|
|
StaticToo;
|
|
>StaticToo : typeof StaticToo
|
|
|
|
// Both!
|
|
function A () {
|
|
>A : typeof A
|
|
|
|
this.x = 1
|
|
>this.x = 1 : 1
|
|
>this.x : any
|
|
>this : this
|
|
>x : any
|
|
>1 : 1
|
|
|
|
/** @type {1} */
|
|
this.second = 1
|
|
>this.second = 1 : 1
|
|
>this.second : 1
|
|
>this : this
|
|
>second : 1
|
|
>1 : 1
|
|
}
|
|
/** @param {number} n */
|
|
A.prototype.z = function f(n) {
|
|
>A.prototype.z = function f(n) { return n + this.x} : (n: number) => number
|
|
>A.prototype.z : any
|
|
>A.prototype : any
|
|
>A : typeof A
|
|
>prototype : any
|
|
>z : any
|
|
>function f(n) { return n + this.x} : (n: number) => number
|
|
>f : (n: number) => number
|
|
>n : number
|
|
|
|
return n + this.x
|
|
>n + this.x : number
|
|
>n : number
|
|
>this.x : number
|
|
>this : this
|
|
>x : number
|
|
}
|
|
/** @param {number} m */
|
|
A.t = function g(m) {
|
|
>A.t = function g(m) { return m + 1} : (m: number) => number
|
|
>A.t : (m: number) => number
|
|
>A : typeof A
|
|
>t : (m: number) => number
|
|
>function g(m) { return m + 1} : (m: number) => number
|
|
>g : (m: number) => number
|
|
>m : number
|
|
|
|
return m + 1
|
|
>m + 1 : number
|
|
>m : number
|
|
>1 : 1
|
|
}
|
|
var a = new A()
|
|
>a : A
|
|
>new A() : A
|
|
>A : typeof A
|
|
|
|
a.z(3)
|
|
>a.z(3) : number
|
|
>a.z : (n: number) => number
|
|
>a : A
|
|
>z : (n: number) => number
|
|
>3 : 3
|
|
|
|
A.t(2)
|
|
>A.t(2) : number
|
|
>A.t : (m: number) => number
|
|
>A : typeof A
|
|
>t : (m: number) => number
|
|
>2 : 2
|
|
|
|
a.second = 1
|
|
>a.second = 1 : 1
|
|
>a.second : 1
|
|
>a : A
|
|
>second : 1
|
|
>1 : 1
|
|
|