diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c8a38f62125e..3f504fe761480 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7802,7 +7802,9 @@ namespace ts { if (isInJSFile(declaration)) { const typeTag = getJSDocType(func); if (typeTag && isFunctionTypeNode(typeTag)) { - return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration)); + const signature = getSignatureFromDeclaration(typeTag); + const pos = func.parameters.indexOf(declaration); + return declaration.dotDotDotToken ? getRestTypeAtPosition(signature, pos) : getTypeAtPosition(signature, pos); } } // Use contextual parameter type if one is available diff --git a/tests/baselines/reference/jsdocFunctionType.errors.txt b/tests/baselines/reference/jsdocFunctionType.errors.txt index 30bd6d7f7f918..c6a105929bfb4 100644 --- a/tests/baselines/reference/jsdocFunctionType.errors.txt +++ b/tests/baselines/reference/jsdocFunctionType.errors.txt @@ -72,4 +72,16 @@ tests/cases/conformance/jsdoc/functions.js(65,14): error TS2345: Argument of typ !!! error TS2345: Argument of type 'typeof E' is not assignable to parameter of type 'new (arg1: number) => { length: number; }'. !!! error TS2345: Property 'length' is missing in type 'E' but required in type '{ length: number; }'. !!! related TS2728 tests/cases/conformance/jsdoc/functions.js:12:28: 'length' is declared here. + + // Repro from #39229 + + /** + * @type {(...args: [string, string] | [number, string, string]) => void} + */ + function foo(...args) { + args; + } + + foo('abc', 'def'); + foo(42, 'abc', 'def'); \ No newline at end of file diff --git a/tests/baselines/reference/jsdocFunctionType.symbols b/tests/baselines/reference/jsdocFunctionType.symbols index 70917e7657c89..194fb63d58f02 100644 --- a/tests/baselines/reference/jsdocFunctionType.symbols +++ b/tests/baselines/reference/jsdocFunctionType.symbols @@ -141,3 +141,22 @@ var y3 = id2(E); >id2 : Symbol(id2, Decl(functions.js, 8, 53)) >E : Symbol(E, Decl(functions.js, 59, 3)) +// Repro from #39229 + +/** + * @type {(...args: [string, string] | [number, string, string]) => void} + */ +function foo(...args) { +>foo : Symbol(foo, Decl(functions.js, 64, 16)) +>args : Symbol(args, Decl(functions.js, 71, 13)) + + args; +>args : Symbol(args, Decl(functions.js, 71, 13)) +} + +foo('abc', 'def'); +>foo : Symbol(foo, Decl(functions.js, 64, 16)) + +foo(42, 'abc', 'def'); +>foo : Symbol(foo, Decl(functions.js, 64, 16)) + diff --git a/tests/baselines/reference/jsdocFunctionType.types b/tests/baselines/reference/jsdocFunctionType.types index f43ce2e84e2e2..d58213ab1ca3a 100644 --- a/tests/baselines/reference/jsdocFunctionType.types +++ b/tests/baselines/reference/jsdocFunctionType.types @@ -165,3 +165,29 @@ var y3 = id2(E); >id2 : (c: new (arg1: number) => { length: number; }) => new (arg1: number) => { length: number; } >E : typeof E +// Repro from #39229 + +/** + * @type {(...args: [string, string] | [number, string, string]) => void} + */ +function foo(...args) { +>foo : (...args: [string, string] | [number, string, string]) => void +>args : [string, string] | [number, string, string] + + args; +>args : [string, string] | [number, string, string] +} + +foo('abc', 'def'); +>foo('abc', 'def') : void +>foo : (...args: [string, string] | [number, string, string]) => void +>'abc' : "abc" +>'def' : "def" + +foo(42, 'abc', 'def'); +>foo(42, 'abc', 'def') : void +>foo : (...args: [string, string] | [number, string, string]) => void +>42 : 42 +>'abc' : "abc" +>'def' : "def" + diff --git a/tests/cases/conformance/jsdoc/jsdocFunctionType.ts b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts index 95c8f8966f19c..48875d52c81f7 100644 --- a/tests/cases/conformance/jsdoc/jsdocFunctionType.ts +++ b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts @@ -70,3 +70,15 @@ var E = function(n) { var y3 = id2(E); + +// Repro from #39229 + +/** + * @type {(...args: [string, string] | [number, string, string]) => void} + */ +function foo(...args) { + args; +} + +foo('abc', 'def'); +foo(42, 'abc', 'def');