fix(42238): emit this parameter in function declaration (#46511)

This commit is contained in:
Oleksandr T 2021-11-18 01:43:27 +02:00 committed by GitHub
parent f11f14baba
commit a75f26e68b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 9 deletions

View File

@ -5657,8 +5657,8 @@ namespace ts {
const expandedParams = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0];
// If the expanded parameter list had a variadic in a non-trailing position, don't expand it
const parameters = (some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(getCheckFlags(p) & CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor, options?.privateSymbolVisitor, options?.bundledImports));
if (signature.thisParameter) {
const thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
const thisParameter = tryGetThisParameterDeclaration(signature, context);
if (thisParameter) {
parameters.unshift(thisParameter);
}
@ -5713,6 +5713,25 @@ namespace ts {
return node;
}
function tryGetThisParameterDeclaration(signature: Signature, context: NodeBuilderContext) {
if (signature.thisParameter) {
return symbolToParameterDeclaration(signature.thisParameter, context);
}
if (signature.declaration) {
const thisTag = getJSDocThisTag(signature.declaration);
if (thisTag && thisTag.typeExpression) {
return factory.createParameterDeclaration(
/* decorators */ undefined,
/* modifiers */ undefined,
/* dotDotDotToken */ undefined,
"this",
/* questionToken */ undefined,
typeToTypeNodeHelper(getTypeFromTypeNode(thisTag.typeExpression), context)
);
}
}
}
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
const savedContextFlags = context.flags;
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic

View File

@ -4,7 +4,7 @@
* @return {number}
*/
function f(s) {
>f : (s: string) => number
>f : (this: { n: number; }, s: string) => number
>s : string
return this.n + s.length
@ -18,11 +18,11 @@ function f(s) {
}
const o = {
>o : { f: (s: string) => number; n: number; }
>{ f, n: 1} : { f: (s: string) => number; n: number; }
>o : { f: (this: { n: number; }, s: string) => number; n: number; }
>{ f, n: 1} : { f: (this: { n: number; }, s: string) => number; n: number; }
f,
>f : (s: string) => number
>f : (this: { n: number; }, s: string) => number
n: 1
>n : number
@ -30,8 +30,8 @@ const o = {
}
o.f('hi')
>o.f('hi') : number
>o.f : (s: string) => number
>o : { f: (s: string) => number; n: number; }
>f : (s: string) => number
>o.f : (this: { n: number; }, s: string) => number
>o : { f: (this: { n: number; }, s: string) => number; n: number; }
>f : (this: { n: number; }, s: string) => number
>'hi' : "hi"

View File

@ -0,0 +1,15 @@
//// [a.js]
/** @this {string} */
export function f1() {}
/** @this */
export function f2() {}
//// [a.d.ts]
/** @this {string} */
export function f1(this: string): void;
/** @this */
export function f2(this: any): void;

View File

@ -0,0 +1,9 @@
=== tests/cases/conformance/jsdoc/a.js ===
/** @this {string} */
export function f1() {}
>f1 : Symbol(f1, Decl(a.js, 0, 0))
/** @this */
export function f2() {}
>f2 : Symbol(f2, Decl(a.js, 1, 23))

View File

@ -0,0 +1,9 @@
=== tests/cases/conformance/jsdoc/a.js ===
/** @this {string} */
export function f1() {}
>f1 : (this: string) => void
/** @this */
export function f2() {}
>f2 : (this: any) => void

View File

@ -0,0 +1,11 @@
// @target: esnext
// @allowJs: true
// @declaration: true
// @emitDeclarationOnly: true
// @filename: a.js
/** @this {string} */
export function f1() {}
/** @this */
export function f2() {}