-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27522 from jack-williams/trailing-void-args-are-o…
…ptional Fix #4260 : Allow trailing arguments that accept void to be omitted
- Loading branch information
Showing
6 changed files
with
913 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
tests/baselines/reference/callWithMissingVoid.errors.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(16,1): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(19,1): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(22,1): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(35,31): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(36,35): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(37,33): error TS2554: Expected 1 arguments, but got 0. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(48,1): error TS2554: Expected 3 arguments, but got 1. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(55,1): error TS2554: Expected 4 arguments, but got 2. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(56,1): error TS2554: Expected 4 arguments, but got 3. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(57,1): error TS2554: Expected 4 arguments, but got 1. | ||
tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts(75,1): error TS2554: Expected 3 arguments, but got 1. | ||
|
||
|
||
==== tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts (11 errors) ==== | ||
// From #4260 | ||
class X<T> { | ||
f(t: T) { | ||
return { a: t }; | ||
} | ||
} | ||
|
||
declare const x: X<void>; | ||
x.f() // no error because f expects void | ||
|
||
declare const xUnion: X<void | number>; | ||
xUnion.f(42) // no error because f accepts number | ||
xUnion.f() // no error because f accepts void | ||
|
||
declare const xAny: X<any>; | ||
xAny.f() // error, any still expects an argument | ||
~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:3:7: An argument for 't' was not provided. | ||
|
||
declare const xUnknown: X<unknown>; | ||
xUnknown.f() // error, unknown still expects an argument | ||
~~~~~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:3:7: An argument for 't' was not provided. | ||
|
||
declare const xNever: X<never>; | ||
xNever.f() // error, never still expects an argument | ||
~~~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:3:7: An argument for 't' was not provided. | ||
|
||
|
||
// Promise has previously been updated to work without arguments, but to show this fixes the issue too. | ||
|
||
class MyPromise<X> { | ||
constructor(executor: (resolve: (value: X) => void) => void) { | ||
|
||
} | ||
} | ||
|
||
new MyPromise<void>(resolve => resolve()); // no error | ||
new MyPromise<void | number>(resolve => resolve()); // no error | ||
new MyPromise<any>(resolve => resolve()); // error, `any` arguments cannot be omitted | ||
~~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:28:38: An argument for 'value' was not provided. | ||
new MyPromise<unknown>(resolve => resolve()); // error, `unknown` arguments cannot be omitted | ||
~~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:28:38: An argument for 'value' was not provided. | ||
new MyPromise<never>(resolve => resolve()); // error, `never` arguments cannot be omitted | ||
~~~~~~~~~ | ||
!!! error TS2554: Expected 1 arguments, but got 0. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:28:38: An argument for 'value' was not provided. | ||
|
||
|
||
// Multiple parameters | ||
|
||
function a(x: number, y: string, z: void): void { | ||
|
||
} | ||
|
||
a(4, "hello"); // ok | ||
a(4, "hello", void 0); // ok | ||
a(4); // not ok | ||
~~~~ | ||
!!! error TS2554: Expected 3 arguments, but got 1. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:42:23: An argument for 'y' was not provided. | ||
|
||
function b(x: number, y: string, z: void, what: number): void { | ||
|
||
} | ||
|
||
b(4, "hello", void 0, 2); // ok | ||
b(4, "hello"); // not ok | ||
~~~~~~~~~~~~~ | ||
!!! error TS2554: Expected 4 arguments, but got 2. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:50:34: An argument for 'z' was not provided. | ||
b(4, "hello", void 0); // not ok | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2554: Expected 4 arguments, but got 3. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:50:43: An argument for 'what' was not provided. | ||
b(4); // not ok | ||
~~~~ | ||
!!! error TS2554: Expected 4 arguments, but got 1. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:50:23: An argument for 'y' was not provided. | ||
|
||
function c(x: number | void, y: void, z: void | string | number): void { | ||
|
||
} | ||
|
||
c(3, void 0, void 0); // ok | ||
c(3, void 0); // ok | ||
c(3); // ok | ||
c(); // ok | ||
|
||
|
||
// Spread Parameters | ||
|
||
declare function call<TS extends unknown[]>( | ||
handler: (...args: TS) => unknown, | ||
...args: TS): void; | ||
|
||
call((x: number, y: number) => x + y) // error | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2554: Expected 3 arguments, but got 1. | ||
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithMissingVoid.ts:73:5: An argument for 'args' was not provided. | ||
call((x: number, y: number) => x + y, 4, 2) // ok | ||
|
||
call((x: number, y: void) => x, 4, void 0) // ok | ||
call((x: number, y: void) => x, 4) // ok | ||
call((x: void, y: void) => 42) // ok | ||
call((x: number | void, y: number | void) => 42) // ok | ||
call((x: number | void, y: number | void) => 42, 4) // ok | ||
call((x: number | void, y: number | void) => 42, 4, 2) // ok | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
//// [callWithMissingVoid.ts] | ||
// From #4260 | ||
class X<T> { | ||
f(t: T) { | ||
return { a: t }; | ||
} | ||
} | ||
|
||
declare const x: X<void>; | ||
x.f() // no error because f expects void | ||
|
||
declare const xUnion: X<void | number>; | ||
xUnion.f(42) // no error because f accepts number | ||
xUnion.f() // no error because f accepts void | ||
|
||
declare const xAny: X<any>; | ||
xAny.f() // error, any still expects an argument | ||
|
||
declare const xUnknown: X<unknown>; | ||
xUnknown.f() // error, unknown still expects an argument | ||
|
||
declare const xNever: X<never>; | ||
xNever.f() // error, never still expects an argument | ||
|
||
|
||
// Promise has previously been updated to work without arguments, but to show this fixes the issue too. | ||
|
||
class MyPromise<X> { | ||
constructor(executor: (resolve: (value: X) => void) => void) { | ||
|
||
} | ||
} | ||
|
||
new MyPromise<void>(resolve => resolve()); // no error | ||
new MyPromise<void | number>(resolve => resolve()); // no error | ||
new MyPromise<any>(resolve => resolve()); // error, `any` arguments cannot be omitted | ||
new MyPromise<unknown>(resolve => resolve()); // error, `unknown` arguments cannot be omitted | ||
new MyPromise<never>(resolve => resolve()); // error, `never` arguments cannot be omitted | ||
|
||
|
||
// Multiple parameters | ||
|
||
function a(x: number, y: string, z: void): void { | ||
|
||
} | ||
|
||
a(4, "hello"); // ok | ||
a(4, "hello", void 0); // ok | ||
a(4); // not ok | ||
|
||
function b(x: number, y: string, z: void, what: number): void { | ||
|
||
} | ||
|
||
b(4, "hello", void 0, 2); // ok | ||
b(4, "hello"); // not ok | ||
b(4, "hello", void 0); // not ok | ||
b(4); // not ok | ||
|
||
function c(x: number | void, y: void, z: void | string | number): void { | ||
|
||
} | ||
|
||
c(3, void 0, void 0); // ok | ||
c(3, void 0); // ok | ||
c(3); // ok | ||
c(); // ok | ||
|
||
|
||
// Spread Parameters | ||
|
||
declare function call<TS extends unknown[]>( | ||
handler: (...args: TS) => unknown, | ||
...args: TS): void; | ||
|
||
call((x: number, y: number) => x + y) // error | ||
call((x: number, y: number) => x + y, 4, 2) // ok | ||
|
||
call((x: number, y: void) => x, 4, void 0) // ok | ||
call((x: number, y: void) => x, 4) // ok | ||
call((x: void, y: void) => 42) // ok | ||
call((x: number | void, y: number | void) => 42) // ok | ||
call((x: number | void, y: number | void) => 42, 4) // ok | ||
call((x: number | void, y: number | void) => 42, 4, 2) // ok | ||
|
||
|
||
//// [callWithMissingVoid.js] | ||
"use strict"; | ||
// From #4260 | ||
var X = /** @class */ (function () { | ||
function X() { | ||
} | ||
X.prototype.f = function (t) { | ||
return { a: t }; | ||
}; | ||
return X; | ||
}()); | ||
x.f(); // no error because f expects void | ||
xUnion.f(42); // no error because f accepts number | ||
xUnion.f(); // no error because f accepts void | ||
xAny.f(); // error, any still expects an argument | ||
xUnknown.f(); // error, unknown still expects an argument | ||
xNever.f(); // error, never still expects an argument | ||
// Promise has previously been updated to work without arguments, but to show this fixes the issue too. | ||
var MyPromise = /** @class */ (function () { | ||
function MyPromise(executor) { | ||
} | ||
return MyPromise; | ||
}()); | ||
new MyPromise(function (resolve) { return resolve(); }); // no error | ||
new MyPromise(function (resolve) { return resolve(); }); // no error | ||
new MyPromise(function (resolve) { return resolve(); }); // error, `any` arguments cannot be omitted | ||
new MyPromise(function (resolve) { return resolve(); }); // error, `unknown` arguments cannot be omitted | ||
new MyPromise(function (resolve) { return resolve(); }); // error, `never` arguments cannot be omitted | ||
// Multiple parameters | ||
function a(x, y, z) { | ||
} | ||
a(4, "hello"); // ok | ||
a(4, "hello", void 0); // ok | ||
a(4); // not ok | ||
function b(x, y, z, what) { | ||
} | ||
b(4, "hello", void 0, 2); // ok | ||
b(4, "hello"); // not ok | ||
b(4, "hello", void 0); // not ok | ||
b(4); // not ok | ||
function c(x, y, z) { | ||
} | ||
c(3, void 0, void 0); // ok | ||
c(3, void 0); // ok | ||
c(3); // ok | ||
c(); // ok | ||
call(function (x, y) { return x + y; }); // error | ||
call(function (x, y) { return x + y; }, 4, 2); // ok | ||
call(function (x, y) { return x; }, 4, void 0); // ok | ||
call(function (x, y) { return x; }, 4); // ok | ||
call(function (x, y) { return 42; }); // ok | ||
call(function (x, y) { return 42; }); // ok | ||
call(function (x, y) { return 42; }, 4); // ok | ||
call(function (x, y) { return 42; }, 4, 2); // ok |
Oops, something went wrong.