diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 125e492cc3..9ff1c4b41b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6855,6 +6855,7 @@ namespace ts { case "Object": return anyType; case "Function": + case "function": return globalFunctionType; case "Array": case "array": diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 07d4a9ada4..2d0a4b66a1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6075,7 +6075,10 @@ namespace ts { case SyntaxKind.OpenBraceToken: return parseJSDocRecordType(); case SyntaxKind.FunctionKeyword: - return parseJSDocFunctionType(); + if (lookAhead(nextTokenIsOpenParen)) { + return parseJSDocFunctionType(); + } + break; case SyntaxKind.DotDotDotToken: return parseJSDocVariadicType(); case SyntaxKind.NewKeyword: @@ -6091,7 +6094,6 @@ namespace ts { case SyntaxKind.NullKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: return parseTokenNode(); case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -6769,7 +6771,7 @@ namespace ts { const jsDocTypeReference = typeExpression.type; if (jsDocTypeReference.name.kind === SyntaxKind.Identifier) { const name = jsDocTypeReference.name; - if (name.text === "Object") { + if (name.text === "Object" || name.text === "object") { typedefTag.jsDocTypeLiteral = scanChildTags(); } } diff --git a/tests/baselines/reference/checkJsdocTypeTag1.js b/tests/baselines/reference/checkJsdocTypeTag1.js index aee738550e..e4586643c2 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.js +++ b/tests/baselines/reference/checkJsdocTypeTag1.js @@ -18,6 +18,10 @@ anyT1 = "hi"; const x = (a) => a + 1; x(1); +/** @type {function} */ +const y = (a) => a + 1; +x(1); + /** @type {function (number)} */ const x1 = (a) => a + 1; x1(0); @@ -41,6 +45,9 @@ anyT1 = "hi"; /** @type {Function} */ var x = function (a) { return a + 1; }; x(1); +/** @type {function} */ +var y = function (a) { return a + 1; }; +x(1); /** @type {function (number)} */ var x1 = function (a) { return a + 1; }; x1(0); diff --git a/tests/baselines/reference/checkJsdocTypeTag1.types b/tests/baselines/reference/checkJsdocTypeTag1.types index 4c6597ca14..9368640edc 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.types +++ b/tests/baselines/reference/checkJsdocTypeTag1.types @@ -44,6 +44,20 @@ x(1); >x : Function >1 : 1 +/** @type {function} */ +const y = (a) => a + 1; +>y : Function +>(a) => a + 1 : (a: any) => any +>a : any +>a + 1 : any +>a : any +>1 : 1 + +x(1); +>x(1) : any +>x : Function +>1 : 1 + /** @type {function (number)} */ const x1 = (a) => a + 1; >x1 : (arg0: number) => any diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js index d4983bfd58..cc2e302ffc 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js @@ -6,12 +6,29 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { + opts.x; +} -foo({x: 'abc'}); +foo({x: 'abc'}); + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({x: 'abc'}); + //// [0.js] // @ts-check @@ -24,5 +41,20 @@ foo({x: 'abc'}); * * @param {Opts} opts */ -function foo(opts) { } +function foo(opts) { + opts.x; +} foo({ x: 'abc' }); +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({ x: 'abc' }); diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols index cd2455797b..844c4c045a 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols @@ -6,14 +6,42 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { >foo : Symbol(foo, Decl(0.js, 0, 0)) >opts : Symbol(opts, Decl(0.js, 10, 13)) + opts.x; +>opts.x : Symbol(x, Decl(0.js, 3, 3)) +>opts : Symbol(opts, Decl(0.js, 10, 13)) +>x : Symbol(x, Decl(0.js, 3, 3)) +} + foo({x: 'abc'}); >foo : Symbol(foo, Decl(0.js, 0, 0)) ->x : Symbol(x, Decl(0.js, 12, 5)) +>x : Symbol(x, Decl(0.js, 14, 5)) + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { +>foo1 : Symbol(foo1, Decl(0.js, 14, 16)) +>opts : Symbol(opts, Decl(0.js, 25, 14)) + + opts.x; +>opts.x : Symbol(x, Decl(0.js, 18, 3)) +>opts : Symbol(opts, Decl(0.js, 25, 14)) +>x : Symbol(x, Decl(0.js, 18, 3)) +} +foo1({x: 'abc'}); +>foo1 : Symbol(foo1, Decl(0.js, 14, 16)) +>x : Symbol(x, Decl(0.js, 28, 6)) diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types index cc923e3303..cb21ea2ef0 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types @@ -6,13 +6,19 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { >foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void >opts : { x: string; y?: string; z?: string; w?: string; } + opts.x; +>opts.x : string +>opts : { x: string; y?: string; z?: string; w?: string; } +>x : string +} + foo({x: 'abc'}); >foo({x: 'abc'}) : void >foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void @@ -20,3 +26,28 @@ foo({x: 'abc'}); >x : string >'abc' : "abc" +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { +>foo1 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void +>opts : { x: string; y?: string; z?: string; w?: string; } + + opts.x; +>opts.x : string +>opts : { x: string; y?: string; z?: string; w?: string; } +>x : string +} +foo1({x: 'abc'}); +>foo1({x: 'abc'}) : void +>foo1 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void +>{x: 'abc'} : { x: string; } +>x : string +>'abc' : "abc" + diff --git a/tests/baselines/reference/jsDocTypeTag2.js b/tests/baselines/reference/jsDocTypeTag2.js index 07535dcee0..d54b4557f0 100644 --- a/tests/baselines/reference/jsDocTypeTag2.js +++ b/tests/baselines/reference/jsDocTypeTag2.js @@ -431,28 +431,8 @@ "kind": "space" }, { - "text": "(", - "kind": "punctuation" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "=>", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "any", - "kind": "keyword" + "text": "Function", + "kind": "localName" } ], "documentation": [], diff --git a/tests/baselines/reference/jsDocTypedef1.js b/tests/baselines/reference/jsDocTypedef1.js new file mode 100644 index 0000000000..28410ee879 --- /dev/null +++ b/tests/baselines/reference/jsDocTypedef1.js @@ -0,0 +1,234 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/jsDocTypedef1.js", + "position": 189 + }, + "quickInfo": { + "kind": "parameter", + "kindModifiers": "", + "textSpan": { + "start": 189, + "length": 4 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "parameter", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "opts", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "x", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "y", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "z", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "w", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/jsDocTypedef1.js", + "position": 424 + }, + "quickInfo": { + "kind": "parameter", + "kindModifiers": "", + "textSpan": { + "start": 424, + "length": 5 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "parameter", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "opts1", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "documentation": [], + "tags": [] + } + } +] \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts b/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts index fe3ea76cfc..fbed9d83b2 100644 --- a/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts +++ b/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts @@ -21,6 +21,10 @@ anyT1 = "hi"; const x = (a) => a + 1; x(1); +/** @type {function} */ +const y = (a) => a + 1; +x(1); + /** @type {function (number)} */ const x1 = (a) => a + 1; x1(0); diff --git a/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts b/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts index 80ca21bd4f..fa885b9f31 100644 --- a/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts +++ b/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts @@ -9,9 +9,25 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { + opts.x; +} -foo({x: 'abc'}); \ No newline at end of file +foo({x: 'abc'}); + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({x: 'abc'}); diff --git a/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts b/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts new file mode 100644 index 0000000000..eea17f182e --- /dev/null +++ b/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts @@ -0,0 +1,33 @@ +/// +// @allowJs: true +// @Filename: jsDocTypedef1.js +//// /** +//// * @typedef {Object} Opts +//// * @property {string} x +//// * @property {string=} y +//// * @property {string} [z] +//// * @property {string} [w="hi"] +//// * +//// * @param {Opts} opts +//// */ +//// function foo(/*1*/opts) { +//// opts.x; +///// } + +//// foo({x: 'abc'}); + +//// /** +//// * @typedef {object} Opts1 +//// * @property {string} x +//// * @property {string=} y +//// * @property {string} [z] +//// * @property {string} [w="hi"] +//// * +//// * @param {Opts1} opts +//// */ +//// function foo1(/*2*/opts1) { +//// opts1.x; +//// } +//// foo1({x: 'abc'}); + +verify.baselineQuickInfo(); \ No newline at end of file