diff --git a/types/node/child_process.d.ts b/types/node/child_process.d.ts index 412258d8bb..cff058d163 100644 --- a/types/node/child_process.d.ts +++ b/types/node/child_process.d.ts @@ -92,6 +92,24 @@ declare module "child_process" { ]; } + // return this object when stdio option is a tuple of 3 + interface ChildProcessByStdio< + I extends null | Writable, + O extends null | Readable, + E extends null | Readable, + > extends ChildProcess { + stdin: I; + stdout: O; + stderr: E; + readonly stdio: [ + I, + O, + E, + Readable | Writable | null | undefined, // extra, no modification + Readable | Writable | null | undefined // extra, no modification + ]; + } + interface MessageOptions { keepOpen?: boolean; } @@ -128,9 +146,99 @@ declare module "child_process" { stdio?: 'pipe' | Array; } + type StdioNull = 'inherit' | 'ignore' | Stream; + type StdioPipe = undefined | null | 'pipe'; + + interface SpawnOptionsWithStdioTuple< + Stdin extends StdioNull | StdioPipe, + Stdout extends StdioNull | StdioPipe, + Stderr extends StdioNull | StdioPipe, + > extends SpawnOptions { + stdio: [Stdin, Stdout, Stderr]; + } + + // overloads of spawn without 'args' function spawn(command: string, options?: SpawnOptionsWithoutStdio): ChildProcessWithoutNullStreams; + + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn(command: string, options: SpawnOptions): ChildProcess; + + // overloads of spawn with 'args' function spawn(command: string, args?: ReadonlyArray, options?: SpawnOptionsWithoutStdio): ChildProcessWithoutNullStreams; + + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn( + command: string, + args: ReadonlyArray, + options: SpawnOptionsWithStdioTuple, + ): ChildProcessByStdio; + function spawn(command: string, args: ReadonlyArray, options: SpawnOptions): ChildProcess; interface ExecOptions extends CommonOptions { diff --git a/types/node/test/child_process.ts b/types/node/test/child_process.ts index c7876a9ac7..2c2d399b75 100644 --- a/types/node/test/child_process.ts +++ b/types/node/test/child_process.ts @@ -308,6 +308,57 @@ async function testPromisify() { expectNonNull(childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [null, null, null] })); expectNonNull(childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['pipe', 'pipe', 'pipe'] })); + function expectStdio(...cps: Array<{ + stdin: Stdin, + stdout: Stdout, + stderr: Stderr, + stdio: [Stdin, Stdout, Stderr, any, any] + }>): void { + return undefined; + } + + expectStdio( + childProcess.spawn('command', { stdio: ['pipe', 'pipe', 'pipe'] }), + childProcess.spawn('command', { stdio: [null, null, null] }), + childProcess.spawn('command', { stdio: [undefined, undefined, undefined] }), + childProcess.spawn('command', { stdio: ['pipe', null, undefined] }), + ); + + expectStdio( + childProcess.spawn('command', { stdio: ['pipe', 'pipe', 'ignore'] }), + childProcess.spawn('command', { stdio: [null, null, 'inherit'] }), + childProcess.spawn('command', { stdio: [undefined, undefined, process.stdout] }), + childProcess.spawn('command', { stdio: ['pipe', null, process.stderr] }), + ); + + expectStdio( + childProcess.spawn('command', { stdio: ['ignore', 'ignore', 'ignore'] }), + childProcess.spawn('command', { stdio: ['inherit', 'inherit', 'inherit'] }), + childProcess.spawn('command', { stdio: [process.stdin, process.stdout, process.stderr] }), + childProcess.spawn('command', { stdio: ['ignore', 'inherit', process.stderr] }), + ); + + expectStdio( + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['pipe', 'pipe', 'pipe'] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [null, null, null] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [undefined, undefined, undefined] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['pipe', null, undefined] }), + ); + + expectStdio( + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['pipe', 'pipe', 'ignore'] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [null, null, 'inherit'] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [undefined, undefined, process.stdout] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['pipe', null, process.stderr] }), + ); + + expectStdio( + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['ignore', 'ignore', 'ignore'] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['inherit', 'inherit', 'inherit'] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: [process.stdin, process.stdout, process.stderr] }), + childProcess.spawn('command', ['a', 'b', 'c'], { stdio: ['ignore', 'inherit', process.stderr] }), + ); + function expectChildProcess(cp: childProcess.ChildProcess): void { return undefined; }