Properly handle rest parameters in function declarations with @type annotations (#39473)

* Properly handle rest parameters in function declarations with @type annotations

* Add tests
This commit is contained in:
Anders Hejlsberg
2020-07-07 16:35:37 -07:00
committed by GitHub
parent d2b32b422f
commit 8c6b85835f
5 changed files with 72 additions and 1 deletions

View File

@@ -7803,7 +7803,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

View File

@@ -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');

View File

@@ -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))

View File

@@ -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"

View File

@@ -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');