Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation about TypeScript types #1015

Merged
merged 1 commit into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ Just like `execa()`, this can [bind options](execution.md#globalshared-options).

## Return value

_Type:_ `ResultPromise`
_TypeScript:_ [`ResultPromise`](typescript.md)\
_Type:_ `Promise<object> | Subprocess`

The return value of all [asynchronous methods](#methods) is both:
- the [subprocess](#subprocess).
Expand All @@ -109,7 +110,7 @@ The return value of all [asynchronous methods](#methods) is both:

## Subprocess

_Type:_ `Subprocess`
_TypeScript:_ [`Subprocess`](typescript.md)

[`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with the following methods and properties.

Expand Down Expand Up @@ -377,6 +378,7 @@ Converts the subprocess to a duplex stream.

## Result

_TypeScript:_ [`Result`](typescript.md) or [`SyncResult`](typescript.md\
_Type:_ `object`

[Result](execution.md#result) of a subprocess successful execution.
Expand Down Expand Up @@ -606,6 +608,7 @@ If a signal terminated the subprocess, this property is defined and included in

## Options

_TypeScript:_ [`Options`](typescript.md) or [`SyncOptions`](typescript.md\
_Type:_ `object`

This lists all options for [`execa()`](#execafile-arguments-options) and the [other methods](#methods).
Expand Down Expand Up @@ -730,6 +733,7 @@ See also the [`input`](#optionsinput) and [`stdin`](#optionsstdin) options.

### options.stdin

_TypeScript:_ [`StdinOption`](typescript.md) or [`StdinSyncOption`](typescript.md)\
_Type:_ `string | number | stream.Readable | ReadableStream | TransformStream | URL | {file: string} | Uint8Array | Iterable<string | Uint8Array | unknown> | AsyncIterable<string | Uint8Array | unknown> | GeneratorFunction<string | Uint8Array | unknown> | AsyncGeneratorFunction<string | Uint8Array | unknown> | {transform: GeneratorFunction | AsyncGeneratorFunction | Duplex | TransformStream}` (or a tuple of those types)\
_Default:_ `'inherit'` with [`$`](#file-arguments-options), `'pipe'` otherwise

Expand All @@ -741,6 +745,7 @@ More info on [available values](input.md), [streaming](streams.md) and [transfor

### options.stdout

_TypeScript:_ [`StdoutStderrOption`](typescript.md) or [`StdoutStderrSyncOption`](typescript.md)\
_Type:_ `string | number | stream.Writable | WritableStream | TransformStream | URL | {file: string} | GeneratorFunction<string | Uint8Array | unknown> | AsyncGeneratorFunction<string | Uint8Array | unknown> | {transform: GeneratorFunction | AsyncGeneratorFunction | Duplex | TransformStream}` (or a tuple of those types)\
_Default:_ `pipe`

Expand All @@ -752,6 +757,7 @@ More info on [available values](output.md), [streaming](streams.md) and [transfo

### options.stderr

_TypeScript:_ [`StdoutStderrOption`](typescript.md) or [`StdoutStderrSyncOption`](typescript.md)\
_Type:_ `string | number | stream.Writable | WritableStream | TransformStream | URL | {file: string} | GeneratorFunction<string | Uint8Array | unknown> | AsyncGeneratorFunction<string | Uint8Array | unknown> | {transform: GeneratorFunction | AsyncGeneratorFunction | Duplex | TransformStream}` (or a tuple of those types)\
_Default:_ `pipe`

Expand All @@ -763,6 +769,7 @@ More info on [available values](output.md), [streaming](streams.md) and [transfo

### options.stdio

_TypeScript:_ [`Options['stdio']`](typescript.md) or [`SyncOptions['stdio']`](typescript.md)\
_Type:_ `string | Array<string | number | stream.Readable | stream.Writable | ReadableStream | WritableStream | TransformStream | URL | {file: string} | Uint8Array | Iterable<string> | Iterable<Uint8Array> | Iterable<unknown> | AsyncIterable<string | Uint8Array | unknown> | GeneratorFunction<string | Uint8Array | unknown> | AsyncGeneratorFunction<string | Uint8Array | unknown> | {transform: GeneratorFunction | AsyncGeneratorFunction | Duplex | TransformStream}>` (or a tuple of those types)\
_Default:_ `pipe`

Expand Down
2 changes: 1 addition & 1 deletion docs/bash.md
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,6 @@ const {pid} = $`npm run build`;

<hr>

[**Next**: 📔 API reference](api.md)\
[**Next**: 🤓 TypeScript](typescript.md)\
[**Previous**: 📎 Windows](windows.md)\
[**Top**: Table of contents](../readme.md#documentation)
139 changes: 139 additions & 0 deletions docs/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../media/logo_dark.svg">
<img alt="execa logo" src="../media/logo.svg" width="400">
</picture>
<br>

# 🤓 TypeScript

## Available types

The following types can be imported: [`ResultPromise`](api.md#return-value), [`Subprocess`](api.md#subprocess), [`Result`](api.md#result), [`ExecaError`](api.md#execaerror), [`Options`](api.md#options), [`StdinOption`](api.md#optionsstdin) and [`StdoutStderrOption`](api.md#optionsstdout).

```ts
import {
execa,
ExecaError,
type ResultPromise,
type Result,
type Options,
type StdinOption,
type StdoutStderrOption,
} from 'execa';

const options: Options = {
stdin: 'inherit' satisfies StdinOption,
stdout: 'pipe' satisfies StdoutStderrOption,
stderr: 'pipe' satisfies StdoutStderrOption,
timeout: 1000,
};

try {
const subprocess: ResultPromise = execa(options)`npm run build`;
const result: Result = await subprocess;
console.log(result.stdout);
} catch (error) {
if (error instanceof ExecaError) {
console.error(error);
}
}
```

## Synchronous execution

Their [synchronous](#synchronous-execution) counterparts are [`SyncResult`](api.md#result), [`ExecaSyncError`](api.md#execasyncerror), [`SyncOptions`](api.md#options), [`StdinSyncOption`](api.md#optionsstdin) and [`StdoutStderrSyncOption`](api.md#optionsstdout).

```ts
import {
execaSync,
ExecaSyncError,
type SyncResult,
type SyncOptions,
type StdinSyncOption,
type StdoutStderrSyncOption,
} from 'execa';

const options: SyncOptions = {
stdin: 'inherit' satisfies StdinSyncOption,
stdout: 'pipe' satisfies StdoutStderrSyncOption,
stderr: 'pipe' satisfies StdoutStderrSyncOption,
timeout: 1000,
};

try {
const result: SyncResult = execaSync(options)`npm run build`;
console.log(result.stdout);
} catch (error) {
if (error instanceof ExecaSyncError) {
console.error(error);
}
}
```

## Type inference

The above examples demonstrate those types. However, types are automatically inferred. Therefore, explicit types are only needed when defining functions that take those values as parameters.

```ts
import {
execa,
ExecaError,
type Result,
} from 'execa';

const printResultStdout = (result: Result) => {
console.log('Stdout', result.stdout);
};

const options = {
stdin: 'inherit',
stdout: 'pipe',
stderr: 'pipe',
timeout: 1000,
} as const;

try {
const subprocess = execa(options)`npm run build`;
const result = await subprocess;
printResultStdout(result);
} catch (error) {
if (error instanceof ExecaError) {
console.error(error);
}
}
```

## Troubleshooting

### Strict unions

Several options are typed as unions. For example, the [`serialization`](api.md#optionsserialization) option's type is `'advanced' | 'json'`, not `string`. Therefore the following example fails:

```ts
import {execa} from 'execa';

// Type error: "No overload matches this call"
const spawnSubprocess = (serialization: string) => execa({serialization})`npm run build`;

// Without `as const`, `options.serialization` is typed as `string`, not `'json'`
const options = {serialization: 'json'};
// Type error: "No overload matches this call"
await execa(options)`npm run build`;
```

But this works:

```ts
import {execa, type Options} from 'execa';

const spawnSubprocess = (serialization: Options['serialization']) => execa({serialization})`npm run build`;

const options = {serialization: 'json'} as const;
await execa(options)`npm run build`;
```

<hr>

[**Next**: 📔 API reference](api.md)\
[**Previous**: 🔍 Differences with Bash and zx](bash.md)\
[**Top**: Table of contents](../readme.md#documentation)
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Advanced usage:
- 🐛 [Debugging](docs/debugging.md)
- 📎 [Windows](docs/windows.md)
- 🔍 [Difference with Bash and zx](docs/bash.md)
- 🤓 [TypeScript](docs/typescript.md)
- 📔 [API reference](docs/api.md)

## Examples
Expand Down