mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Jsdoc @constructor - in constructor properly infer this as class instance (#25980)
* Properly infer `this` in tagged `@constructor`s.
`c.prototype.method = function() { this }` was already supported.
This commit add support to two more kinds relying on the JSDoc
`@constructor` tag. These are:
1. `/** @constructor */ function Example() { this }`
2. `/** @constructor */ var Example = function() { this }`
* Update the baseline for js constructorFunctions.
C3 and C4 `this` was set as `any`, now it is properly showing as
the class type.
* Fix lint errors
* Add circular initialisers to constructo fn tests.
* Error (`TS2348`) if calling tagged js constructors
When calling a JS function explicitly tagged with either `@class` or
`@constructor` the checker should throw a TS2348 not callable error.
* Don't resolve jsdoc classes with construct sigs.
This undoes the last commit that sought to change how js functions
tagged with `@class` were inferred. For some reason, currently
unknown, giving those functions construct signatures causes issues
in property assignment/member resolution (as seen in the
`typeFromPropertyAssignment12` test case).
Instead of changing the signature resolution, the error is explicitly
generated in `resolveCallExpression` for those functions.
This commit is contained in:
committed by
Nathan Shively-Sanders
parent
4821f81ce7
commit
dfedb24f75
+18
-2
@@ -15404,8 +15404,8 @@ namespace ts {
|
||||
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
|
||||
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
|
||||
|
||||
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
|
||||
// of a x.prototype.y = function [name]() { .... }
|
||||
// If this is a function in a JS file, it might be a class method.
|
||||
// Check if it's the RHS of a x.prototype.y = function [name]() { .... }
|
||||
if (container.kind === SyntaxKind.FunctionExpression &&
|
||||
container.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
getSpecialPropertyAssignmentKind(container.parent as BinaryExpression) === SpecialPropertyAssignmentKind.PrototypeProperty) {
|
||||
@@ -15419,6 +15419,17 @@ namespace ts {
|
||||
return getFlowTypeOfReference(node, getInferredClassType(classSymbol));
|
||||
}
|
||||
}
|
||||
// Check if it's a constructor definition, can be either a variable decl or function decl
|
||||
// i.e.
|
||||
// * /** @constructor */ function [name]() { ... }
|
||||
// * /** @constructor */ var x = function() { ... }
|
||||
else if ((container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) &&
|
||||
getJSDocClassTag(container)) {
|
||||
const classType = getJavaScriptClassType(container.symbol);
|
||||
if (classType) {
|
||||
return getFlowTypeOfReference(node, classType);
|
||||
}
|
||||
}
|
||||
|
||||
const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
|
||||
if (thisType) {
|
||||
@@ -19497,6 +19508,11 @@ namespace ts {
|
||||
}
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
// If the function is explicitly marked with `@class`, then it must be constructed.
|
||||
if (callSignatures.some(sig => isInJavaScriptFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) {
|
||||
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user