Skip to content

Improve contextual types using jsdoc tags #16346

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

Merged
merged 4 commits into from
Jun 9, 2017
Merged

Improve contextual types using jsdoc tags #16346

merged 4 commits into from
Jun 9, 2017

Conversation

rbuckton
Copy link
Member

@rbuckton rbuckton commented Jun 8, 2017

This addresses the fact that we do not currently use jsdoc /** @type */ tags when getting the contextual type of a variable declaration in a JavaScript file.

Fixes #15618
Fixes #16109

@rbuckton rbuckton requested review from RyanCavanaugh, mhegazy and a user June 8, 2017 00:28
// @filename: index.js

/** @type {Array<[string, {x?:number, y?:number}]>} */
const arr = [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also test with function return type and get/set accessor types.

@@ -12744,6 +12744,10 @@ namespace ts {
if (declaration.type) {
return getTypeFromTypeNode(declaration.type);
}
const jsDocType = isInJavaScriptFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the style here differs from the case immediately below it, although the two seem to be accomplishing the same thing. I personally prefer the below style (though with if (type) return type; on one line).

if (returnTag && returnTag.typeExpression) {
return getTypeFromTypeNode(returnTag.typeExpression.type);
const jsdocType = getJSDocReturnType(func);
if (jsdocType) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return jsdocType && getTypeFromTypeNode(jsdocType);

if (accessor && accessor.parameters.length > 0) {
const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
return accessor.parameters[hasThis ? 1 : 0].type;
const parameter = accessor.parameters[hasThis ? 1 : 0];
if (parameter) {
Copy link

@ghost ghost Jun 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the if here, since we just checked the length?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Holdover from when I considered splitting this into two functions.

/** Get the type annotaion for the value parameter. */
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
/** Get the type annotation for the value parameter. */
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration, includeJSDocType?: boolean): TypeNode {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't getAnnotatedAccessorType and isGetAccessorWithAnnotatedSetAccessor call this with includeJSDocType? Would it ever hurt to include that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered actually making this a separate function, as getSetAccessorTypeAnnotationNode very clearly states its getting the type annotation, not the jsdoc comment. I don't want to just blindly grab the jsdoc comment.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should JS have different behavior than TS here though? JS users have no option to use a "real" type annotation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getSetAccessorTypeAnnotationNode is used in the transforms as well as the checker. At the point where it is used it is expecting a lexical type annotation node, not an inferred type annotation node.

@rbuckton rbuckton merged commit eadafd2 into master Jun 9, 2017
@rbuckton rbuckton deleted the fix15618 branch June 9, 2017 07:11
@ghost ghost mentioned this pull request Jul 12, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants