diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b145cc83bb9..6ecb7babf95 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12744,9 +12744,11 @@ namespace ts { if (declaration.type) { return getTypeFromTypeNode(declaration.type); } - const jsDocType = isInJavaScriptFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration); - if (jsDocType) { - return jsDocType; + if (isInJavaScriptFile(declaration)) { + const jsDocType = getTypeForDeclarationFromJSDocComment(declaration); + if (jsDocType) { + return jsDocType; + } } if (declaration.kind === SyntaxKind.Parameter) { const type = getContextuallyTypedParameterType(declaration); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 54142e80e61..c6ae9bfc2fd 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2625,13 +2625,11 @@ namespace ts { if (accessor && accessor.parameters.length > 0) { const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]); const parameter = accessor.parameters[hasThis ? 1 : 0]; - if (parameter) { - if (parameter.type) { - return parameter.type; - } - if (includeJSDocType && parameter.flags & NodeFlags.JavaScriptFile) { - return getJSDocType(parameter); - } + if (parameter.type) { + return parameter.type; + } + if (includeJSDocType && parameter.flags & NodeFlags.JavaScriptFile) { + return getJSDocType(parameter); } } } diff --git a/tests/baselines/reference/contextualTypeFromJSDoc.symbols b/tests/baselines/reference/contextualTypeFromJSDoc.symbols index 5826a8d78b7..e2be9362644 100644 --- a/tests/baselines/reference/contextualTypeFromJSDoc.symbols +++ b/tests/baselines/reference/contextualTypeFromJSDoc.symbols @@ -10,3 +10,39 @@ const arr = [ >y : Symbol(y, Decl(index.js, 3, 11)) ]; + +/** @return {function(): Array<[string, {x?:number, y?:number}]>} */ +function f() { +>f : Symbol(f, Decl(index.js, 4, 2)) + + return [ + ['a', { x: 1 }], +>x : Symbol(x, Decl(index.js, 9, 15)) + + ['b', { y: 2 }] +>y : Symbol(y, Decl(index.js, 10, 15)) + + ]; +} + +class C { +>C : Symbol(C, Decl(index.js, 12, 1)) + + /** @param {function(): Array<[string, {x?:number, y?:number}]>} value */ + set x(value) { } +>x : Symbol(C.x, Decl(index.js, 14, 9)) +>value : Symbol(value, Decl(index.js, 16, 10)) + + get () { +>get : Symbol(C.get, Decl(index.js, 16, 20)) + + return [ + ['a', { x: 1 }], +>x : Symbol(x, Decl(index.js, 19, 19)) + + ['b', { y: 2 }] +>y : Symbol(y, Decl(index.js, 20, 19)) + + ]; + } +} diff --git a/tests/baselines/reference/contextualTypeFromJSDoc.types b/tests/baselines/reference/contextualTypeFromJSDoc.types index 6271121bea1..c1d273c8f70 100644 --- a/tests/baselines/reference/contextualTypeFromJSDoc.types +++ b/tests/baselines/reference/contextualTypeFromJSDoc.types @@ -19,3 +19,59 @@ const arr = [ >2 : 2 ]; + +/** @return {function(): Array<[string, {x?:number, y?:number}]>} */ +function f() { +>f : () => () => [string, { x?: number; y?: number; }][] + + return [ +>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ((string | { [x: string]: any; x: number; })[] | (string | { [x: string]: any; y: number; })[])[] + + ['a', { x: 1 }], +>['a', { x: 1 }] : (string | { [x: string]: any; x: number; })[] +>'a' : "a" +>{ x: 1 } : { [x: string]: any; x: number; } +>x : number +>1 : 1 + + ['b', { y: 2 }] +>['b', { y: 2 }] : (string | { [x: string]: any; y: number; })[] +>'b' : "b" +>{ y: 2 } : { [x: string]: any; y: number; } +>y : number +>2 : 2 + + ]; +} + +class C { +>C : C + + /** @param {function(): Array<[string, {x?:number, y?:number}]>} value */ + set x(value) { } +>x : any +>value : () => [string, { x?: number; y?: number; }][] + + get () { +>get : () => ((string | { [x: string]: any; x: number; })[] | (string | { [x: string]: any; y: number; })[])[] + + return [ +>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ((string | { [x: string]: any; x: number; })[] | (string | { [x: string]: any; y: number; })[])[] + + ['a', { x: 1 }], +>['a', { x: 1 }] : (string | { [x: string]: any; x: number; })[] +>'a' : "a" +>{ x: 1 } : { [x: string]: any; x: number; } +>x : number +>1 : 1 + + ['b', { y: 2 }] +>['b', { y: 2 }] : (string | { [x: string]: any; y: number; })[] +>'b' : "b" +>{ y: 2 } : { [x: string]: any; y: number; } +>y : number +>2 : 2 + + ]; + } +} diff --git a/tests/cases/conformance/types/contextualTypes/jsdoc/contextualTypeFromJSDoc.ts b/tests/cases/conformance/types/contextualTypes/jsdoc/contextualTypeFromJSDoc.ts index 07d82bfb4bf..89fdd420d4a 100644 --- a/tests/cases/conformance/types/contextualTypes/jsdoc/contextualTypeFromJSDoc.ts +++ b/tests/cases/conformance/types/contextualTypes/jsdoc/contextualTypeFromJSDoc.ts @@ -2,9 +2,29 @@ // @checkJs: true // @noEmit: true // @filename: index.js +// @target: esnext /** @type {Array<[string, {x?:number, y?:number}]>} */ const arr = [ ['a', { x: 1 }], ['b', { y: 2 }] -]; \ No newline at end of file +]; + +/** @return {function(): Array<[string, {x?:number, y?:number}]>} */ +function f() { + return [ + ['a', { x: 1 }], + ['b', { y: 2 }] + ]; +} + +class C { + /** @param {function(): Array<[string, {x?:number, y?:number}]>} value */ + set x(value) { } + get () { + return [ + ['a', { x: 1 }], + ['b', { y: 2 }] + ]; + } +} \ No newline at end of file