-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Add getEffectiveConstructSignatures #27561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* getEffectiveConstructSignatures gets construct signatures from type, and call signatures from constructor functions if there are no construct signatures. * getEffectiveConstructSignatureReturnType gets the "JS Class type" for constructor functions, and the return type of signatures for all other declarations. This is a first step toward making constructor functions have construct signatures instead of call signatures, which will also contribute to fixing instantiation of generic constructor functions, which is basically broken right now. Note that the baselines *improve* but, because of the previously mentioned generic problem, are still not correct. Construct signatures for constructor functions and generic constructor functions turns out to be an intertwined problem.
And, for now, return anyType for generic constructor functions used as base types. Don't give an incorrect error based on the function's return type, which is usually void.
Rather than adding another pair of if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
type.callSignatures = getSignaturesOfSymbol(symbol);
} with type.constructSignatures = filter(type.callSignatures, sig => isJSConstructor(sig.declaration)); and let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) :
signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) :
getReturnTypeFromAnnotation(signature.declaration!) ||
(nodeIsMissing((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration)); with let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) :
signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) :
isJSConstructor(signature.declaration) ? getJSClassType(getSymbolOfNode(signature.declaration!)) :
getReturnTypeFromAnnotation(signature.declaration!) ||
(nodeIsMissing((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration)); no? |
The latter should definitely work, although I decided to favour The former might have odd effects through out the system, but it is where I want to go, so I'll try it out. |
I thought I got rid of it!
After testing: the results keep the improvements without changing baselines too much, so I think this is a good solution. Thanks @weswigham ! |
It doesn't work, and shouldn't in the future, because it's a runtime error.
This is a first step toward making constructor functions have construct signatures instead of call signatures, which will also contribute to fixing instantiation of generic constructor functions, which is basically broken right now.
Note that the baselines improve but, because of the previously mentioned generic problem, are still not correct. Construct signatures for constructor functions and generic constructor functions turns out to be an intertwined problem.
Specifically, a non-generic class that inherits from a generic constructor function now finds a signature, but can't yet instantiate it, so it just returns any for now. However, the constructor signature itself is correctly instantiated in the ad-hoc code in resolveNewExpression, so in the following example, the arguments are correctly checked but the resulting instance type is
any
:I'll fix this in a separate PR, which will probably be much bigger.