mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
fix(51868): this within function typed as any when annotated with JSDoc (#54516)
This commit is contained in:
parent
38575dc015
commit
df40c7ae88
@ -28473,20 +28473,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeForThisExpressionFromJSDoc(node: Node) {
|
||||
const jsdocType = getJSDocType(node);
|
||||
if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) {
|
||||
const jsDocFunctionType = jsdocType as JSDocFunctionType;
|
||||
if (jsDocFunctionType.parameters.length > 0 &&
|
||||
jsDocFunctionType.parameters[0].name &&
|
||||
(jsDocFunctionType.parameters[0].name as Identifier).escapedText === InternalSymbolName.This) {
|
||||
return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type!);
|
||||
}
|
||||
}
|
||||
function getTypeForThisExpressionFromJSDoc(node: SignatureDeclaration) {
|
||||
const thisTag = getJSDocThisTag(node);
|
||||
if (thisTag && thisTag.typeExpression) {
|
||||
return getTypeFromTypeNode(thisTag.typeExpression);
|
||||
}
|
||||
const signature = getSignatureOfTypeTag(node);
|
||||
if (signature) {
|
||||
return getThisTypeOfSignature(signature);
|
||||
}
|
||||
}
|
||||
|
||||
function isInConstructorArgumentInitializer(node: Node, constructorDecl: Node): boolean {
|
||||
|
||||
58
tests/baselines/reference/jsdocThisType.errors.txt
Normal file
58
tests/baselines/reference/jsdocThisType.errors.txt
Normal file
@ -0,0 +1,58 @@
|
||||
/a.js(3,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
/a.js(8,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
/a.js(13,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
/a.js(18,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
/a.js(23,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
/a.js(28,10): error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
|
||||
|
||||
==== /types.d.ts (0 errors) ====
|
||||
export interface Foo {
|
||||
foo: () => void;
|
||||
}
|
||||
|
||||
export type M = (this: Foo) => void;
|
||||
|
||||
==== /a.js (6 errors) ====
|
||||
/** @type {import('./types').M} */
|
||||
export const f1 = function() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
/** @type {import('./types').M} */
|
||||
export function f2() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export const f3 = function() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export function f4() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export const f5 = function() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export function f6() {
|
||||
this.test();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'test' does not exist on type 'Foo'.
|
||||
}
|
||||
|
||||
62
tests/baselines/reference/jsdocThisType.symbols
Normal file
62
tests/baselines/reference/jsdocThisType.symbols
Normal file
@ -0,0 +1,62 @@
|
||||
=== /types.d.ts ===
|
||||
export interface Foo {
|
||||
>Foo : Symbol(Foo, Decl(types.d.ts, 0, 0))
|
||||
|
||||
foo: () => void;
|
||||
>foo : Symbol(Foo.foo, Decl(types.d.ts, 0, 22))
|
||||
}
|
||||
|
||||
export type M = (this: Foo) => void;
|
||||
>M : Symbol(M, Decl(types.d.ts, 2, 1))
|
||||
>this : Symbol(this, Decl(types.d.ts, 4, 17))
|
||||
>Foo : Symbol(Foo, Decl(types.d.ts, 0, 0))
|
||||
|
||||
=== /a.js ===
|
||||
/** @type {import('./types').M} */
|
||||
export const f1 = function() {
|
||||
>f1 : Symbol(f1, Decl(a.js, 1, 12))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(this, Decl(types.d.ts, 4, 17))
|
||||
}
|
||||
|
||||
/** @type {import('./types').M} */
|
||||
export function f2() {
|
||||
>f2 : Symbol(f2, Decl(a.js, 3, 1))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(Foo, Decl(types.d.ts, 0, 0))
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export const f3 = function() {
|
||||
>f3 : Symbol(f3, Decl(a.js, 11, 12))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(this, Decl(a.js, 10, 12))
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export function f4() {
|
||||
>f4 : Symbol(f4, Decl(a.js, 13, 1))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(Foo, Decl(types.d.ts, 0, 0))
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export const f5 = function() {
|
||||
>f5 : Symbol(f5, Decl(a.js, 21, 12))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(this, Decl(a.js, 20, 20))
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export function f6() {
|
||||
>f6 : Symbol(f6, Decl(a.js, 23, 1))
|
||||
|
||||
this.test();
|
||||
>this : Symbol(Foo, Decl(types.d.ts, 0, 0))
|
||||
}
|
||||
|
||||
80
tests/baselines/reference/jsdocThisType.types
Normal file
80
tests/baselines/reference/jsdocThisType.types
Normal file
@ -0,0 +1,80 @@
|
||||
=== /types.d.ts ===
|
||||
export interface Foo {
|
||||
foo: () => void;
|
||||
>foo : () => void
|
||||
}
|
||||
|
||||
export type M = (this: Foo) => void;
|
||||
>M : (this: Foo) => void
|
||||
>this : Foo
|
||||
|
||||
=== /a.js ===
|
||||
/** @type {import('./types').M} */
|
||||
export const f1 = function() {
|
||||
>f1 : import("/types").M
|
||||
>function() { this.test();} : (this: import("/types").Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
/** @type {import('./types').M} */
|
||||
export function f2() {
|
||||
>f2 : (this: import("/types").Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export const f3 = function() {
|
||||
>f3 : (this: import("/types").Foo) => void
|
||||
>function() { this.test();} : (this: import("/types").Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export function f4() {
|
||||
>f4 : (this: import('./types').Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export const f5 = function() {
|
||||
>f5 : (this: import("/types").Foo) => void
|
||||
>function() { this.test();} : (this: import("/types").Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export function f6() {
|
||||
>f6 : (this: import('./types').Foo) => void
|
||||
|
||||
this.test();
|
||||
>this.test() : any
|
||||
>this.test : any
|
||||
>this : import("/types").Foo
|
||||
>test : any
|
||||
}
|
||||
|
||||
41
tests/cases/conformance/jsdoc/jsdocThisType.ts
Normal file
41
tests/cases/conformance/jsdoc/jsdocThisType.ts
Normal file
@ -0,0 +1,41 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @filename: /types.d.ts
|
||||
export interface Foo {
|
||||
foo: () => void;
|
||||
}
|
||||
|
||||
export type M = (this: Foo) => void;
|
||||
|
||||
// @filename: /a.js
|
||||
/** @type {import('./types').M} */
|
||||
export const f1 = function() {
|
||||
this.test();
|
||||
}
|
||||
|
||||
/** @type {import('./types').M} */
|
||||
export function f2() {
|
||||
this.test();
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export const f3 = function() {
|
||||
this.test();
|
||||
}
|
||||
|
||||
/** @type {(this: import('./types').Foo) => void} */
|
||||
export function f4() {
|
||||
this.test();
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export const f5 = function() {
|
||||
this.test();
|
||||
}
|
||||
|
||||
/** @type {function(this: import('./types').Foo): void} */
|
||||
export function f6() {
|
||||
this.test();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user