Simplify arity errors, rewording spread errors (#43855)

* Scribbles + tests

The second test actually requires node types

* Basically working

The two simple fixes, in arity error reporting, are in, and the
simplification of arity error reporting is half-done. I haven't started
on any improvements to call assignability.

* trim out too-real test case

* Finish cleanup

And reword error a little.

* Simplify and reword spread errors

* handle spreads first

* update baselines

* Address PR comments
This commit is contained in:
Nathan Shively-Sanders
2021-04-29 14:38:50 -07:00
committed by GitHub
parent 4ecb563aa4
commit 004b3ae018
26 changed files with 522 additions and 135 deletions
+48 -69
View File
@@ -28613,88 +28613,67 @@ namespace ts {
}
function getArgumentArityError(node: CallLikeExpression, signatures: readonly Signature[], args: readonly Expression[]) {
let min = Number.POSITIVE_INFINITY;
let max = Number.NEGATIVE_INFINITY;
let belowArgCount = Number.NEGATIVE_INFINITY;
let aboveArgCount = Number.POSITIVE_INFINITY;
const spreadIndex = getSpreadArgumentIndex(args);
if (spreadIndex > -1) {
return createDiagnosticForNode(args[spreadIndex], Diagnostics.A_spread_argument_must_either_have_a_tuple_type_or_be_passed_to_a_rest_parameter);
}
let min = Number.POSITIVE_INFINITY; // smallest parameter count
let max = Number.NEGATIVE_INFINITY; // largest parameter count
let maxBelow = Number.NEGATIVE_INFINITY; // largest parameter count that is smaller than the number of arguments
let minAbove = Number.POSITIVE_INFINITY; // smallest parameter count that is larger than the number of arguments
let argCount = args.length;
let closestSignature: Signature | undefined;
for (const sig of signatures) {
const minCount = getMinArgumentCount(sig);
const maxCount = getParameterCount(sig);
if (minCount < argCount && minCount > belowArgCount) belowArgCount = minCount;
if (argCount < maxCount && maxCount < aboveArgCount) aboveArgCount = maxCount;
if (minCount < min) {
min = minCount;
const minParameter = getMinArgumentCount(sig);
const maxParameter = getParameterCount(sig);
// smallest/largest parameter counts
if (minParameter < min) {
min = minParameter;
closestSignature = sig;
}
max = Math.max(max, maxCount);
max = Math.max(max, maxParameter);
// shortest parameter count *longer than the call*/longest parameter count *shorter than the call*
if (minParameter < args.length && minParameter > maxBelow) maxBelow = minParameter;
if (args.length < maxParameter && maxParameter < minAbove) minAbove = maxParameter;
}
if (min < argCount && argCount < max) {
return getDiagnosticForCallNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
}
const hasRestParameter = some(signatures, hasEffectiveRestParameter);
const paramRange = hasRestParameter ? min :
min < max ? min + "-" + max :
min;
const hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
if (argCount <= max && hasSpreadArgument) {
argCount--;
const parameterRange = hasRestParameter ? min
: min < max ? min + "-" + max
: min;
const error = hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1
: parameterRange === 1 && args.length === 0 && isPromiseResolveArityError(node) ? Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise
: Diagnostics.Expected_0_arguments_but_got_1;
if (min < args.length && args.length < max) {
// between min and max, but with no matching overload
return getDiagnosticForCallNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, args.length, maxBelow, minAbove);
}
let spanArray: NodeArray<Node>;
let related: DiagnosticWithLocation | undefined;
const error = hasRestParameter || hasSpreadArgument ?
hasRestParameter && hasSpreadArgument ?
Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
hasRestParameter ?
Diagnostics.Expected_at_least_0_arguments_but_got_1 :
Diagnostics.Expected_0_arguments_but_got_1_or_more :
paramRange === 1 && argCount === 0 && isPromiseResolveArityError(node) ?
Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise :
Diagnostics.Expected_0_arguments_but_got_1;
if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
const paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
if (paramDecl) {
related = createDiagnosticForNode(
paramDecl,
isBindingPattern(paramDecl.name) ? Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided :
isRestParameter(paramDecl) ? Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided : Diagnostics.An_argument_for_0_was_not_provided,
!paramDecl.name ? argCount : !isBindingPattern(paramDecl.name) ? idText(getFirstIdentifier(paramDecl.name)) : undefined
else if (args.length < min) {
// too short: put the error span on the call expression, not any of the args
const diagnostic = getDiagnosticForCallNode(node, error, parameterRange, args.length);
const parameter = closestSignature?.declaration?.parameters[closestSignature.thisParameter ? args.length + 1 : args.length];
if (parameter) {
const parameterError = createDiagnosticForNode(
parameter,
isBindingPattern(parameter.name) ? Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided
: isRestParameter(parameter) ? Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided
: Diagnostics.An_argument_for_0_was_not_provided,
!parameter.name ? args.length : !isBindingPattern(parameter.name) ? idText(getFirstIdentifier(parameter.name)) : undefined
);
return addRelatedInfo(diagnostic, parameterError);
}
}
if (!hasSpreadArgument && argCount < min) {
const diagnostic = getDiagnosticForCallNode(node, error, paramRange, argCount);
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
}
if (hasRestParameter || hasSpreadArgument) {
spanArray = factory.createNodeArray(args);
if (hasSpreadArgument && argCount) {
const nextArg = elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
spanArray = factory.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
}
return diagnostic;
}
else {
spanArray = factory.createNodeArray(args.slice(max));
// too long; error goes on the excess parameters
const errorSpan = factory.createNodeArray(args.slice(max));
const pos = first(errorSpan).pos;
let end = last(errorSpan).end;
if (end === pos) {
end++;
}
setTextRangePosEnd(errorSpan, pos, end);
return createDiagnosticForNodeArray(getSourceFileOfNode(node), errorSpan, error, parameterRange, args.length);
}
const pos = first(spanArray).pos;
let end = last(spanArray).end;
if (end === pos) {
end++;
}
setTextRangePosEnd(spanArray, pos, end);
const diagnostic = createDiagnosticForNodeArray(
getSourceFileOfNode(node), spanArray, error, paramRange, argCount);
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
}
function getTypeArgumentArityError(node: Node, signatures: readonly Signature[], typeArguments: NodeArray<TypeNode>) {
+1 -5
View File
@@ -2386,14 +2386,10 @@
"category": "Error",
"code": 2555
},
"Expected {0} arguments, but got {1} or more.": {
"A spread argument must either have a tuple type or be passed to a rest parameter.": {
"category": "Error",
"code": 2556
},
"Expected at least {0} arguments, but got {1} or more.": {
"category": "Error",
"code": 2557
},
"Expected {0} type arguments, but got {1}.": {
"category": "Error",
"code": 2558
@@ -1,7 +1,7 @@
tests/cases/conformance/expressions/functionCalls/callOverload.ts(7,7): error TS2554: Expected 1 arguments, but got 4.
tests/cases/conformance/expressions/functionCalls/callOverload.ts(8,15): error TS2554: Expected 2 arguments, but got 4.
tests/cases/conformance/expressions/functionCalls/callOverload.ts(10,1): error TS2555: Expected at least 1 arguments, but got 0.
tests/cases/conformance/expressions/functionCalls/callOverload.ts(11,10): error TS2557: Expected at least 1 arguments, but got 0 or more.
tests/cases/conformance/expressions/functionCalls/callOverload.ts(11,10): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/expressions/functionCalls/callOverload.ts (4 errors) ====
@@ -24,5 +24,4 @@ tests/cases/conformance/expressions/functionCalls/callOverload.ts(11,10): error
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callOverload.ts:3:27: An argument for 'a' was not provided.
withRest(...n);
~~~~
!!! error TS2557: Expected at least 1 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callOverload.ts:3:27: An argument for 'a' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,5 +1,5 @@
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(23,13): error TS2556: Expected 1 arguments, but got 2 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(24,7): error TS2556: Expected 0 arguments, but got 1 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(23,13): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(24,7): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(27,5): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(28,5): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
@@ -9,10 +9,10 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(30,13): err
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(31,11): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(32,11): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(33,8): error TS2556: Expected 1-3 arguments, but got 0 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(34,8): error TS2556: Expected 1-3 arguments, but got 0 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(33,8): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(34,8): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(35,8): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(36,14): error TS2556: Expected 2-4 arguments, but got 1 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(36,14): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts (12 errors) ====
@@ -40,10 +40,10 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(36,14): err
// extra arguments
normal("g", ...ns)
~~~~~
!!! error TS2556: Expected 1 arguments, but got 2 or more.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
thunk(...ns)
~~~~~
!!! error TS2556: Expected 0 arguments, but got 1 or more.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
// bad
all(...mixed)
@@ -69,17 +69,14 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(36,14): err
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
prefix(...ns) // required parameters are required
~~~~~
!!! error TS2556: Expected 1-3 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts:3:25: An argument for 's' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
prefix(...mixed)
~~~~~~~~
!!! error TS2556: Expected 1-3 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts:3:25: An argument for 's' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
prefix(...tuple)
~~~~~~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
prefix2("g", ...ns);
~~~~~
!!! error TS2556: Expected 2-4 arguments, but got 1 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts:7:37: An argument for 'n' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -4,12 +4,12 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(16,15): err
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(17,15): error TS2554: Expected 2 arguments, but got 6.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(18,12): error TS2554: Expected 2 arguments, but got 3.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(19,5): error TS2554: Expected 2 arguments, but got 3.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(20,6): error TS2557: Expected at least 2 arguments, but got 0 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(20,6): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(21,6): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(22,13): error TS2557: Expected at least 2 arguments, but got 1 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(23,13): error TS2557: Expected at least 2 arguments, but got 2 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(22,6): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(23,6): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(25,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(31,13): error TS2557: Expected at least 2 arguments, but got 4 or more.
tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(31,6): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts (12 errors) ====
@@ -46,18 +46,16 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(31,13): err
!!! error TS2554: Expected 2 arguments, but got 3.
fs2_(...s_); // error on ...s_
~~~~~
!!! error TS2557: Expected at least 2 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts:9:23: An argument for 'a' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
fs2_(...s2n_); // error on ...s2n_
~~~~~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
fs2_(...s_, ...s_); // error FIXME: bad error message
~~~~~
!!! error TS2557: Expected at least 2 arguments, but got 1 or more.
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts:9:34: An argument for 'b' was not provided.
fs2_(...s_, ...s_, ...s_); // error FIXME: worse error message
~~~~~~~~~~~~
!!! error TS2557: Expected at least 2 arguments, but got 2 or more.
fs2_(...s_, ...s_); // error on ...s_
~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
fs2_(...s_, ...s_, ...s_); // error on ...s_
~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
// fs2n_(...s2, ...s_); // FIXME: should be a type error
fs2n_(...s2_); // error on ...s2_
~~~~~~
@@ -68,8 +66,8 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(31,13): err
fs2_(...s2_, ...s_);
fs2_(...s2_, ...s2_);
fs2_(...s_, ...s2_);
~~~~~~
!!! error TS2557: Expected at least 2 arguments, but got 4 or more.
~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
fs2n_(...s2n_);
fs2n_(...s2);
// fs2n_(...s2, ...n_); // FIXME: should compile
+4 -4
View File
@@ -20,8 +20,8 @@ fs2(...s2, 'a'); // error on 'a'
fs2(...s3); // error on ...s3
fs2_(...s_); // error on ...s_
fs2_(...s2n_); // error on ...s2n_
fs2_(...s_, ...s_); // error FIXME: bad error message
fs2_(...s_, ...s_, ...s_); // error FIXME: worse error message
fs2_(...s_, ...s_); // error on ...s_
fs2_(...s_, ...s_, ...s_); // error on ...s_
// fs2n_(...s2, ...s_); // FIXME: should be a type error
fs2n_(...s2_); // error on ...s2_
@@ -51,8 +51,8 @@ fs2.apply(void 0, __spreadArray(__spreadArray([], s2), ['a'])); // error on 'a'
fs2.apply(void 0, s3); // error on ...s3
fs2_.apply(void 0, s_); // error on ...s_
fs2_.apply(void 0, s2n_); // error on ...s2n_
fs2_.apply(void 0, __spreadArray(__spreadArray([], s_), s_)); // error FIXME: bad error message
fs2_.apply(void 0, __spreadArray(__spreadArray(__spreadArray([], s_), s_), s_)); // error FIXME: worse error message
fs2_.apply(void 0, __spreadArray(__spreadArray([], s_), s_)); // error on ...s_
fs2_.apply(void 0, __spreadArray(__spreadArray(__spreadArray([], s_), s_), s_)); // error on ...s_
// fs2n_(...s2, ...s_); // FIXME: should be a type error
fs2n_.apply(void 0, s2_); // error on ...s2_
// ok
@@ -75,12 +75,12 @@ fs2_(...s2n_); // error on ...s2n_
>fs2_ : Symbol(fs2_, Decl(callWithSpread3.ts, 7, 49))
>s2n_ : Symbol(s2n_, Decl(callWithSpread3.ts, 5, 13))
fs2_(...s_, ...s_); // error FIXME: bad error message
fs2_(...s_, ...s_); // error on ...s_
>fs2_ : Symbol(fs2_, Decl(callWithSpread3.ts, 7, 49))
>s_ : Symbol(s_, Decl(callWithSpread3.ts, 3, 13))
>s_ : Symbol(s_, Decl(callWithSpread3.ts, 3, 13))
fs2_(...s_, ...s_, ...s_); // error FIXME: worse error message
fs2_(...s_, ...s_, ...s_); // error on ...s_
>fs2_ : Symbol(fs2_, Decl(callWithSpread3.ts, 7, 49))
>s_ : Symbol(s_, Decl(callWithSpread3.ts, 3, 13))
>s_ : Symbol(s_, Decl(callWithSpread3.ts, 3, 13))
@@ -103,7 +103,7 @@ fs2_(...s2n_); // error on ...s2n_
>...s2n_ : string | number
>s2n_ : [string, string, ...number[]]
fs2_(...s_, ...s_); // error FIXME: bad error message
fs2_(...s_, ...s_); // error on ...s_
>fs2_(...s_, ...s_) : void
>fs2_ : (a: string, b: string, ...c: string[]) => void
>...s_ : string
@@ -111,7 +111,7 @@ fs2_(...s_, ...s_); // error FIXME: bad error message
>...s_ : string
>s_ : string[]
fs2_(...s_, ...s_, ...s_); // error FIXME: worse error message
fs2_(...s_, ...s_, ...s_); // error on ...s_
>fs2_(...s_, ...s_, ...s_) : void
>fs2_ : (a: string, b: string, ...c: string[]) => void
>...s_ : string
@@ -0,0 +1,39 @@
tests/cases/conformance/expressions/functionCalls/callWithSpread4.ts(18,5): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/expressions/functionCalls/callWithSpread4.ts(27,6): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/expressions/functionCalls/callWithSpread4.ts (2 errors) ====
type R = { a: number }
type W = { b: number }
type RW = { a: number, b: number }
declare const pli: {
(s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>;
(streams: ReadonlyArray<R | W | RW>): Promise<void>;
(s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>;
}
declare var writes: W
declare var reads: R
declare var tr: W
declare var gun: RW[]
declare var gz: RW[]
declare var fun: (inp: any) => AsyncGenerator<string, void, unknown>
pli(
reads,
...gun,
~~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tr,
fun,
...gz,
writes
);
declare function test(x: any, y: () => string): string | undefined;
declare var anys: any[]
test(...anys)
~~~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
pli(...[reads, writes, writes] as const)
@@ -0,0 +1,37 @@
//// [callWithSpread4.ts]
type R = { a: number }
type W = { b: number }
type RW = { a: number, b: number }
declare const pli: {
(s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>;
(streams: ReadonlyArray<R | W | RW>): Promise<void>;
(s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>;
}
declare var writes: W
declare var reads: R
declare var tr: W
declare var gun: RW[]
declare var gz: RW[]
declare var fun: (inp: any) => AsyncGenerator<string, void, unknown>
pli(
reads,
...gun,
tr,
fun,
...gz,
writes
);
declare function test(x: any, y: () => string): string | undefined;
declare var anys: any[]
test(...anys)
pli(...[reads, writes, writes] as const)
//// [callWithSpread4.js]
"use strict";
pli(reads, ...gun, tr, fun, ...gz, writes);
test(...anys);
pli(...[reads, writes, writes]);
@@ -0,0 +1,117 @@
=== tests/cases/conformance/expressions/functionCalls/callWithSpread4.ts ===
type R = { a: number }
>R : Symbol(R, Decl(callWithSpread4.ts, 0, 0))
>a : Symbol(a, Decl(callWithSpread4.ts, 0, 10))
type W = { b: number }
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
>b : Symbol(b, Decl(callWithSpread4.ts, 1, 10))
type RW = { a: number, b: number }
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>a : Symbol(a, Decl(callWithSpread4.ts, 2, 11))
>b : Symbol(b, Decl(callWithSpread4.ts, 2, 22))
declare const pli: {
>pli : Symbol(pli, Decl(callWithSpread4.ts, 3, 13))
(s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>;
>s1 : Symbol(s1, Decl(callWithSpread4.ts, 4, 5))
>R : Symbol(R, Decl(callWithSpread4.ts, 0, 0))
>s2 : Symbol(s2, Decl(callWithSpread4.ts, 4, 11))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>s3 : Symbol(s3, Decl(callWithSpread4.ts, 4, 19))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>s4 : Symbol(s4, Decl(callWithSpread4.ts, 4, 27))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>s5 : Symbol(s5, Decl(callWithSpread4.ts, 4, 35))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
(streams: ReadonlyArray<R | W | RW>): Promise<void>;
>streams : Symbol(streams, Decl(callWithSpread4.ts, 5, 5))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.es2019.array.d.ts, --, --))
>R : Symbol(R, Decl(callWithSpread4.ts, 0, 0))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
(s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>;
>s1 : Symbol(s1, Decl(callWithSpread4.ts, 6, 5))
>R : Symbol(R, Decl(callWithSpread4.ts, 0, 0))
>s2 : Symbol(s2, Decl(callWithSpread4.ts, 6, 11))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
>streams : Symbol(streams, Decl(callWithSpread4.ts, 6, 23))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more)
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
}
declare var writes: W
>writes : Symbol(writes, Decl(callWithSpread4.ts, 9, 11))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
declare var reads: R
>reads : Symbol(reads, Decl(callWithSpread4.ts, 10, 11))
>R : Symbol(R, Decl(callWithSpread4.ts, 0, 0))
declare var tr: W
>tr : Symbol(tr, Decl(callWithSpread4.ts, 11, 11))
>W : Symbol(W, Decl(callWithSpread4.ts, 0, 22))
declare var gun: RW[]
>gun : Symbol(gun, Decl(callWithSpread4.ts, 12, 11))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
declare var gz: RW[]
>gz : Symbol(gz, Decl(callWithSpread4.ts, 13, 11))
>RW : Symbol(RW, Decl(callWithSpread4.ts, 1, 22))
declare var fun: (inp: any) => AsyncGenerator<string, void, unknown>
>fun : Symbol(fun, Decl(callWithSpread4.ts, 14, 11))
>inp : Symbol(inp, Decl(callWithSpread4.ts, 14, 18))
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
pli(
>pli : Symbol(pli, Decl(callWithSpread4.ts, 3, 13))
reads,
>reads : Symbol(reads, Decl(callWithSpread4.ts, 10, 11))
...gun,
>gun : Symbol(gun, Decl(callWithSpread4.ts, 12, 11))
tr,
>tr : Symbol(tr, Decl(callWithSpread4.ts, 11, 11))
fun,
>fun : Symbol(fun, Decl(callWithSpread4.ts, 14, 11))
...gz,
>gz : Symbol(gz, Decl(callWithSpread4.ts, 13, 11))
writes
>writes : Symbol(writes, Decl(callWithSpread4.ts, 9, 11))
);
declare function test(x: any, y: () => string): string | undefined;
>test : Symbol(test, Decl(callWithSpread4.ts, 22, 2))
>x : Symbol(x, Decl(callWithSpread4.ts, 24, 22))
>y : Symbol(y, Decl(callWithSpread4.ts, 24, 29))
declare var anys: any[]
>anys : Symbol(anys, Decl(callWithSpread4.ts, 25, 11))
test(...anys)
>test : Symbol(test, Decl(callWithSpread4.ts, 22, 2))
>anys : Symbol(anys, Decl(callWithSpread4.ts, 25, 11))
pli(...[reads, writes, writes] as const)
>pli : Symbol(pli, Decl(callWithSpread4.ts, 3, 13))
>reads : Symbol(reads, Decl(callWithSpread4.ts, 10, 11))
>writes : Symbol(writes, Decl(callWithSpread4.ts, 9, 11))
>writes : Symbol(writes, Decl(callWithSpread4.ts, 9, 11))
@@ -0,0 +1,102 @@
=== tests/cases/conformance/expressions/functionCalls/callWithSpread4.ts ===
type R = { a: number }
>R : R
>a : number
type W = { b: number }
>W : W
>b : number
type RW = { a: number, b: number }
>RW : RW
>a : number
>b : number
declare const pli: {
>pli : { (s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>; (streams: ReadonlyArray<R | W | RW>): Promise<void>; (s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>; }
(s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>;
>s1 : R
>s2 : RW
>s3 : RW
>s4 : RW
>s5 : W
(streams: ReadonlyArray<R | W | RW>): Promise<void>;
>streams : readonly (R | W | RW)[]
(s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>;
>s1 : R
>s2 : W | RW
>streams : (W | RW)[]
}
declare var writes: W
>writes : W
declare var reads: R
>reads : R
declare var tr: W
>tr : W
declare var gun: RW[]
>gun : RW[]
declare var gz: RW[]
>gz : RW[]
declare var fun: (inp: any) => AsyncGenerator<string, void, unknown>
>fun : (inp: any) => AsyncGenerator<string, void, unknown>
>inp : any
pli(
>pli( reads, ...gun, tr, fun, ...gz, writes) : Promise<void>
>pli : { (s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>; (streams: readonly (R | W | RW)[]): Promise<void>; (s1: R, s2: W | RW, ...streams: (W | RW)[]): Promise<void>; }
reads,
>reads : R
...gun,
>...gun : RW
>gun : RW[]
tr,
>tr : W
fun,
>fun : (inp: any) => AsyncGenerator<string, void, unknown>
...gz,
>...gz : RW
>gz : RW[]
writes
>writes : W
);
declare function test(x: any, y: () => string): string | undefined;
>test : (x: any, y: () => string) => string | undefined
>x : any
>y : () => string
declare var anys: any[]
>anys : any[]
test(...anys)
>test(...anys) : string | undefined
>test : (x: any, y: () => string) => string | undefined
>...anys : any
>anys : any[]
pli(...[reads, writes, writes] as const)
>pli(...[reads, writes, writes] as const) : Promise<void>
>pli : { (s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>; (streams: readonly (R | W | RW)[]): Promise<void>; (s1: R, s2: W | RW, ...streams: (W | RW)[]): Promise<void>; }
>...[reads, writes, writes] as const : R | W
>[reads, writes, writes] as const : readonly [R, W, W]
>[reads, writes, writes] : readonly [R, W, W]
>reads : R
>writes : W
>writes : W
@@ -0,0 +1,14 @@
tests/cases/conformance/expressions/functionCalls/callWithSpread5.ts(7,4): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/expressions/functionCalls/callWithSpread5.ts (1 errors) ====
declare const x: number
declare const nnnu: [number, number, number?]
declare const nntnnnt: [number, number] | [number, number, number]
declare function fn(a: number, b: number, bb: number, ...c: number[]): number
fn(...nnnu, x)
fn(...nntnnnt, x)
~~~~~~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -0,0 +1,18 @@
//// [callWithSpread5.ts]
declare const x: number
declare const nnnu: [number, number, number?]
declare const nntnnnt: [number, number] | [number, number, number]
declare function fn(a: number, b: number, bb: number, ...c: number[]): number
fn(...nnnu, x)
fn(...nntnnnt, x)
//// [callWithSpread5.js]
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
fn.apply(void 0, __spreadArray(__spreadArray([], nnnu), [x]));
fn.apply(void 0, __spreadArray(__spreadArray([], nntnnnt), [x]));
@@ -0,0 +1,27 @@
=== tests/cases/conformance/expressions/functionCalls/callWithSpread5.ts ===
declare const x: number
>x : Symbol(x, Decl(callWithSpread5.ts, 0, 13))
declare const nnnu: [number, number, number?]
>nnnu : Symbol(nnnu, Decl(callWithSpread5.ts, 1, 13))
declare const nntnnnt: [number, number] | [number, number, number]
>nntnnnt : Symbol(nntnnnt, Decl(callWithSpread5.ts, 2, 13))
declare function fn(a: number, b: number, bb: number, ...c: number[]): number
>fn : Symbol(fn, Decl(callWithSpread5.ts, 2, 66))
>a : Symbol(a, Decl(callWithSpread5.ts, 3, 20))
>b : Symbol(b, Decl(callWithSpread5.ts, 3, 30))
>bb : Symbol(bb, Decl(callWithSpread5.ts, 3, 41))
>c : Symbol(c, Decl(callWithSpread5.ts, 3, 53))
fn(...nnnu, x)
>fn : Symbol(fn, Decl(callWithSpread5.ts, 2, 66))
>nnnu : Symbol(nnnu, Decl(callWithSpread5.ts, 1, 13))
>x : Symbol(x, Decl(callWithSpread5.ts, 0, 13))
fn(...nntnnnt, x)
>fn : Symbol(fn, Decl(callWithSpread5.ts, 2, 66))
>nntnnnt : Symbol(nntnnnt, Decl(callWithSpread5.ts, 2, 13))
>x : Symbol(x, Decl(callWithSpread5.ts, 0, 13))
@@ -0,0 +1,31 @@
=== tests/cases/conformance/expressions/functionCalls/callWithSpread5.ts ===
declare const x: number
>x : number
declare const nnnu: [number, number, number?]
>nnnu : [number, number, number?]
declare const nntnnnt: [number, number] | [number, number, number]
>nntnnnt : [number, number] | [number, number, number]
declare function fn(a: number, b: number, bb: number, ...c: number[]): number
>fn : (a: number, b: number, bb: number, ...c: number[]) => number
>a : number
>b : number
>bb : number
>c : number[]
fn(...nnnu, x)
>fn(...nnnu, x) : number
>fn : (a: number, b: number, bb: number, ...c: number[]) => number
>...nnnu : number
>nnnu : [number, number, number?]
>x : number
fn(...nntnnnt, x)
>fn(...nntnnnt, x) : number
>fn : (a: number, b: number, bb: number, ...c: number[]) => number
>...nntnnnt : number
>nntnnnt : [number, number] | [number, number, number]
>x : number
@@ -5,7 +5,7 @@ tests/cases/compiler/functionParameterArityMismatch.ts(11,1): error TS2575: No o
tests/cases/compiler/functionParameterArityMismatch.ts(12,1): error TS2575: No overload expects 3 arguments, but overloads do exist that expect either 2 or 4 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(13,1): error TS2575: No overload expects 5 arguments, but overloads do exist that expect either 4 or 6 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(14,22): error TS2554: Expected 0-6 arguments, but got 7.
tests/cases/compiler/functionParameterArityMismatch.ts(15,12): error TS2556: Expected 0-6 arguments, but got 5 or more.
tests/cases/compiler/functionParameterArityMismatch.ts(15,4): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/compiler/functionParameterArityMismatch.ts (8 errors) ====
@@ -39,6 +39,6 @@ tests/cases/compiler/functionParameterArityMismatch.ts(15,12): error TS2556: Exp
~
!!! error TS2554: Expected 0-6 arguments, but got 7.
f2(...[1], 2, 3, 4, 5, 6);
~~~~~~~~~~~~~
!!! error TS2556: Expected 0-6 arguments, but got 5 or more.
~~~~~~
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,4 +1,4 @@
tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,5): error TS2556: Expected 1 arguments, but got 0 or more.
tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,5): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts (1 errors) ====
@@ -18,5 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,5): error TS2556:
foo(...new SymbolIterator);
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2556: Expected 1 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts:1:14: An argument for 's' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,4 +1,4 @@
tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,5): error TS2556: Expected 1 arguments, but got 0 or more.
tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,5): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts (1 errors) ====
@@ -18,5 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,5): error TS2556
foo(...new SymbolIterator);
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2556: Expected 1 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts:1:17: An argument for 's' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,4 +1,4 @@
tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,5): error TS2556: Expected 1 arguments, but got 0 or more.
tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,5): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts (1 errors) ====
@@ -18,5 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,5): error TS2556:
foo(...new SymbolIterator);
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2556: Expected 1 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts:1:14: An argument for 's' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,4 +1,4 @@
tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,5): error TS2557: Expected at least 1 arguments, but got 0 or more.
tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,5): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts (1 errors) ====
@@ -18,5 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,5): error TS2557:
foo(...new SymbolIterator);
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2557: Expected at least 1 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts:1:14: An argument for 's1' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
@@ -1,4 +1,4 @@
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,16): error TS2556: Expected 0 arguments, but got 1 or more.
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,16): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'number' is not an array type.
@@ -8,7 +8,7 @@ tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'number
while (1) {
bar = ~foo(...bar);
~~~~~~
!!! error TS2556: Expected 0 arguments, but got 1 or more.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
~~~
!!! error TS2461: Type 'number' is not an array type.
}
@@ -1,4 +1,4 @@
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(8,8): error TS2556: Expected 2 arguments, but got 0 or more.
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(8,8): error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(20,15): error TS2554: Expected 2 arguments, but got 3.
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(25,5): error TS2542: Index signature in type 'readonly string[]' only permits reading.
@@ -13,8 +13,7 @@ tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(25,5): erro
function f1(...args: readonly string[]) {
f0(...args); // Error
~~~~~~~
!!! error TS2556: Expected 2 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts:1:13: An argument for 'a' was not provided.
!!! error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
@@ -19,8 +19,8 @@ fs2(...s2, 'a'); // error on 'a'
fs2(...s3); // error on ...s3
fs2_(...s_); // error on ...s_
fs2_(...s2n_); // error on ...s2n_
fs2_(...s_, ...s_); // error FIXME: bad error message
fs2_(...s_, ...s_, ...s_); // error FIXME: worse error message
fs2_(...s_, ...s_); // error on ...s_
fs2_(...s_, ...s_, ...s_); // error on ...s_
// fs2n_(...s2, ...s_); // FIXME: should be a type error
fs2n_(...s2_); // error on ...s2_
@@ -0,0 +1,31 @@
// @strict: true
// @target: esnext
type R = { a: number }
type W = { b: number }
type RW = { a: number, b: number }
declare const pli: {
(s1: R, s2: RW, s3: RW, s4: RW, s5: W): Promise<void>;
(streams: ReadonlyArray<R | W | RW>): Promise<void>;
(s1: R, s2: RW | W, ...streams: Array<RW | W>): Promise<void>;
}
declare var writes: W
declare var reads: R
declare var tr: W
declare var gun: RW[]
declare var gz: RW[]
declare var fun: (inp: any) => AsyncGenerator<string, void, unknown>
pli(
reads,
...gun,
tr,
fun,
...gz,
writes
);
declare function test(x: any, y: () => string): string | undefined;
declare var anys: any[]
test(...anys)
pli(...[reads, writes, writes] as const)
@@ -0,0 +1,7 @@
declare const x: number
declare const nnnu: [number, number, number?]
declare const nntnnnt: [number, number] | [number, number, number]
declare function fn(a: number, b: number, bb: number, ...c: number[]): number
fn(...nnnu, x)
fn(...nntnnnt, x)