Skip to content

getJSDocReturnType gets return type from @type tags #25486

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
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 16 additions & 42 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5022,14 +5022,27 @@ namespace ts {
}

/**
* Gets the return type node for the node if provided via JSDoc's return tag.
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
*
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
* gets the type from inside the braces.
* gets the type from inside the braces, after the fat arrow, etc.
*/
export function getJSDocReturnType(node: Node): TypeNode | undefined {
const returnTag = getJSDocReturnTag(node);
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
if (returnTag && returnTag.typeExpression) {
return returnTag.typeExpression.type;
}
const typeTag = getJSDocTypeTag(node);
if (typeTag && typeTag.typeExpression) {
const type = typeTag.typeExpression.type;
if (isTypeLiteralNode(type)) {
const sig = find(type.members, isCallSignatureDeclaration);
return sig && sig.type;
}
if (isFunctionTypeNode(type)) {
return type.type;
}
}
}

/** Get all JSDoc tags related to a node, including those on parent nodes. */
Expand Down Expand Up @@ -6572,45 +6585,6 @@ namespace ts {
return !!(node as HasType).type;
}

/* True if the node could have a type node a `.type` */
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 discovered this function was unused and deleted it along the way.

/* @internal */
export function couldHaveType(node: Node): node is HasType {
switch (node.kind) {
case SyntaxKind.Parameter:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.TypePredicate:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.ParenthesizedType:
case SyntaxKind.TypeOperator:
case SyntaxKind.MappedType:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.AsExpression:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.JSDocTypeExpression:
case SyntaxKind.JSDocNullableType:
case SyntaxKind.JSDocNonNullableType:
case SyntaxKind.JSDocOptionalType:
case SyntaxKind.JSDocFunctionType:
case SyntaxKind.JSDocVariadicType:
return true;
}
return false;
}

/** True if has initializer node attached to it. */
/* @internal */
export function hasInitializer(node: Node): node is HasInitializer {
Expand Down
5 changes: 2 additions & 3 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6777,10 +6777,10 @@ declare namespace ts {
*/
function getJSDocType(node: Node): TypeNode | undefined;
/**
* Gets the return type node for the node if provided via JSDoc's return tag.
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
*
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
* gets the type from inside the braces.
* gets the type from inside the braces, after the fat arrow, etc.
*/
function getJSDocReturnType(node: Node): TypeNode | undefined;
/** Get all JSDoc tags related to a node, including those on parent nodes. */
Expand Down Expand Up @@ -7072,7 +7072,6 @@ declare namespace ts {
function hasJSDocNodes(node: Node): node is HasJSDoc;
/** True if has type node attached to it. */
function hasType(node: Node): node is HasType;
function couldHaveType(node: Node): node is HasType;
/** True if has initializer node attached to it. */
function hasInitializer(node: Node): node is HasInitializer;
/** True if has initializer node attached to it. */
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3227,10 +3227,10 @@ declare namespace ts {
*/
function getJSDocType(node: Node): TypeNode | undefined;
/**
* Gets the return type node for the node if provided via JSDoc's return tag.
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
*
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
* gets the type from inside the braces.
* gets the type from inside the braces, after the fat arrow, etc.
*/
function getJSDocReturnType(node: Node): TypeNode | undefined;
/** Get all JSDoc tags related to a node, including those on parent nodes. */
Expand Down
36 changes: 36 additions & 0 deletions tests/baselines/reference/checkJsdocTypeTag5.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
tests/cases/conformance/jsdoc/test.js(3,17): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(5,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(7,24): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(10,17): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(12,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(14,24): error TS2322: Type 'number' is not assignable to type 'string'.


==== tests/cases/conformance/jsdoc/test.js (6 errors) ====
// all 6 should error on return statement/expression
/** @type {(x: number) => string} */
function h(x) { return x }
~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
/** @type {(x: number) => string} */
var f = x => x
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
/** @type {(x: number) => string} */
var g = function (x) { return x }
~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

/** @type {{ (x: number): string }} */
function i(x) { return x }
~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
/** @type {{ (x: number): string }} */
var j = x => x
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
/** @type {{ (x: number): string }} */
var k = function (x) { return x }
~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

38 changes: 38 additions & 0 deletions tests/baselines/reference/checkJsdocTypeTag5.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
=== tests/cases/conformance/jsdoc/test.js ===
// all 6 should error on return statement/expression
/** @type {(x: number) => string} */
function h(x) { return x }
>h : Symbol(h, Decl(test.js, 0, 0))
>x : Symbol(x, Decl(test.js, 2, 11))
>x : Symbol(x, Decl(test.js, 2, 11))

/** @type {(x: number) => string} */
var f = x => x
>f : Symbol(f, Decl(test.js, 4, 3))
>x : Symbol(x, Decl(test.js, 4, 7))
>x : Symbol(x, Decl(test.js, 4, 7))

/** @type {(x: number) => string} */
var g = function (x) { return x }
>g : Symbol(g, Decl(test.js, 6, 3))
>x : Symbol(x, Decl(test.js, 6, 18))
>x : Symbol(x, Decl(test.js, 6, 18))

/** @type {{ (x: number): string }} */
function i(x) { return x }
>i : Symbol(i, Decl(test.js, 6, 33))
>x : Symbol(x, Decl(test.js, 9, 11))
>x : Symbol(x, Decl(test.js, 9, 11))

/** @type {{ (x: number): string }} */
var j = x => x
>j : Symbol(j, Decl(test.js, 11, 3))
>x : Symbol(x, Decl(test.js, 11, 7))
>x : Symbol(x, Decl(test.js, 11, 7))

/** @type {{ (x: number): string }} */
var k = function (x) { return x }
>k : Symbol(k, Decl(test.js, 13, 3))
>x : Symbol(x, Decl(test.js, 13, 18))
>x : Symbol(x, Decl(test.js, 13, 18))

42 changes: 42 additions & 0 deletions tests/baselines/reference/checkJsdocTypeTag5.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
=== tests/cases/conformance/jsdoc/test.js ===
// all 6 should error on return statement/expression
/** @type {(x: number) => string} */
function h(x) { return x }
>h : (x: number) => string
>x : number
>x : number

/** @type {(x: number) => string} */
var f = x => x
>f : (x: number) => string
>x => x : (x: number) => string
>x : number
>x : number

/** @type {(x: number) => string} */
var g = function (x) { return x }
>g : (x: number) => string
>function (x) { return x } : (x: number) => string
>x : number
>x : number

/** @type {{ (x: number): string }} */
function i(x) { return x }
>i : (x: number) => string
>x : number
>x : number

/** @type {{ (x: number): string }} */
var j = x => x
>j : (x: number) => string
>x => x : (x: number) => string
>x : number
>x : number

/** @type {{ (x: number): string }} */
var k = function (x) { return x }
>k : (x: number) => string
>function (x) { return x } : (x: number) => string
>x : number
>x : number

18 changes: 18 additions & 0 deletions tests/cases/conformance/jsdoc/checkJsdocTypeTag5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @Filename: test.js
// all 6 should error on return statement/expression
/** @type {(x: number) => string} */
function h(x) { return x }
/** @type {(x: number) => string} */
var f = x => x
/** @type {(x: number) => string} */
var g = function (x) { return x }

/** @type {{ (x: number): string }} */
function i(x) { return x }
/** @type {{ (x: number): string }} */
var j = x => x
/** @type {{ (x: number): string }} */
var k = function (x) { return x }