From 2d8475291b260aa79d2654793d9f6e8db88c06eb Mon Sep 17 00:00:00 2001 From: ehmicky Date: Fri, 10 May 2024 19:26:20 +0100 Subject: [PATCH] Export `TemplateExpression` type (#1049) --- docs/typescript.md | 15 ++++++++++----- index.d.ts | 1 + test-d/methods/template.test-d.ts | 18 ++++++++++++++++++ types/methods/template.d.ts | 4 +++- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 test-d/methods/template.test-d.ts diff --git a/docs/typescript.md b/docs/typescript.md index 0b8a741cca..fbbb5f5fdf 100644 --- a/docs/typescript.md +++ b/docs/typescript.md @@ -8,7 +8,7 @@ ## 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). +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), [`StdoutStderrOption`](api.md#optionsstdout) and [`TemplateExpression`](api.md#execacommand). ```ts import { @@ -19,6 +19,7 @@ import { type Options, type StdinOption, type StdoutStderrOption, + type TemplateExpression, } from 'execa'; const options: Options = { @@ -27,9 +28,10 @@ const options: Options = { stderr: 'pipe' satisfies StdoutStderrOption, timeout: 1000, }; +const task: TemplateExpression = 'build'; try { - const subprocess: ResultPromise = execa(options)`npm run build`; + const subprocess: ResultPromise = execa(options)`npm run ${task}`; const result: Result = await subprocess; console.log(result.stdout); } catch (error) { @@ -41,7 +43,7 @@ try { ## 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). +Their [synchronous](#synchronous-execution) counterparts are [`SyncResult`](api.md#result), [`ExecaSyncError`](api.md#execasyncerror), [`SyncOptions`](api.md#options), [`StdinSyncOption`](api.md#optionsstdin), [`StdoutStderrSyncOption`](api.md#optionsstdout) and [`TemplateExpression`](api.md#execacommand). ```ts import { @@ -51,6 +53,7 @@ import { type SyncOptions, type StdinSyncOption, type StdoutStderrSyncOption, + type TemplateExpression, } from 'execa'; const options: SyncOptions = { @@ -59,9 +62,10 @@ const options: SyncOptions = { stderr: 'pipe' satisfies StdoutStderrSyncOption, timeout: 1000, }; +const task: TemplateExpression = 'build'; try { - const result: SyncResult = execaSync(options)`npm run build`; + const result: SyncResult = execaSync(options)`npm run ${task}`; console.log(result.stdout); } catch (error) { if (error instanceof ExecaSyncError) { @@ -91,9 +95,10 @@ const options = { stderr: 'pipe', timeout: 1000, } as const; +const task = 'build'; try { - const subprocess = execa(options)`npm run build`; + const subprocess = execa(options)`npm run ${task}`; const result = await subprocess; printResultStdout(result); } catch (error) { diff --git a/index.d.ts b/index.d.ts index fd64d3bfd2..344c4c2f15 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,6 +8,7 @@ export type {Options, SyncOptions} from './types/arguments/options.js'; export type {Result, SyncResult} from './types/return/result.js'; export type {ResultPromise, Subprocess} from './types/subprocess/subprocess.js'; export {ExecaError, ExecaSyncError} from './types/return/final-error.js'; +export type {TemplateExpression} from './types/methods/template.js'; export {execa} from './types/methods/main-async.js'; export {execaSync} from './types/methods/main-sync.js'; export {execaCommand, execaCommandSync} from './types/methods/command.js'; diff --git a/test-d/methods/template.test-d.ts b/test-d/methods/template.test-d.ts new file mode 100644 index 0000000000..5aa836d498 --- /dev/null +++ b/test-d/methods/template.test-d.ts @@ -0,0 +1,18 @@ +import {expectAssignable, expectNotAssignable} from 'tsd'; +import {execa, type TemplateExpression} from '../../index.js'; + +const stringArray = ['foo', 'bar'] as const; +const numberArray = [1, 2] as const; + +expectAssignable('unicorns'); +expectAssignable(1); +expectAssignable(stringArray); +expectAssignable(numberArray); +expectAssignable(false.toString()); +expectNotAssignable(false); + +expectAssignable(await execa`echo foo`); +expectAssignable(await execa({reject: false})`echo foo`); +expectNotAssignable(execa`echo foo`); +expectAssignable([await execa`echo foo`, 'bar']); +expectNotAssignable([execa`echo foo`, 'bar']); diff --git a/types/methods/template.d.ts b/types/methods/template.d.ts index 189a18986f..012d31990e 100644 --- a/types/methods/template.d.ts +++ b/types/methods/template.d.ts @@ -1,12 +1,14 @@ import type {Result, SyncResult} from '../return/result.js'; -// Values allowed inside `...${...}...` template syntax type TemplateExpressionItem = | string | number | Result | SyncResult; +/** +Value allowed inside `${...}` when using the template string syntax. +*/ export type TemplateExpression = TemplateExpressionItem | readonly TemplateExpressionItem[]; // `...${...}...` template syntax