#typescript
#typescript
Вопрос:
Пытаюсь преобразовать эту функцию в typescript:
const runProcess = (...proc) => {
const proc = child_process.spawn(...proc, {
stdio: ["ignore", "pipe", "pipe"],
});
Можно ли это сделать? В этом конкретном случае procs может быть либо одной строкой, либо 2-кортежем (как представить это в TS?), состоящим из строки и массива строк.
Комментарии:
1. Да, это можно сделать. Какой тип
child_process.spawn
ожидается?
Ответ №1:
Для создания кортежа вы просто помещаете типы внутри квадратных скобок в том порядке, в котором они появляются. [string, string[]]
это тип для 2-го кортежа a string
и массива строк ( string[]
) .
Поскольку мы распределяем аргументы runProcess
и обрабатываем их как массив, нам нужно обрабатывать другой тип аргумента — одну строку — как 1-кортеж [string]
.
Мы говорим, что наши аргументы proc
являются одним из этих двух кортежей : [string] | [string, string[]]
. Поэтому мы знаем, что первым элементом в массиве args всегда является a string
, а вторым элементом является либо string[]
или undefined
. Для вызова child_process.spawn
мы хотим по умолчанию использовать пустой массив для второго аргумента, если он не задан.
Эта подпись выглядит так:
const runProcess = (...proc: [string] | [string, string[]]) => {
const [str, arr = []] = proc;
const child = child_process.spawn(str, arr, {
stdio: ["ignore", "pipe", "pipe"],
});
}
Но, учитывая, что мы всегда имеем дело ровно с одним или двумя аргументами, я не уверен, что действительно имеет смысл распространять аргументы как ...proc
. Почему бы просто не иметь обязательный первый аргумент и необязательный второй аргумент, который по умолчанию равен пустому массиву?
const runProcess = (command: string, args: string[] = []) => {
const proc = child_process.spawn(command, args, {
stdio: ["ignore", "pipe", "pipe"],
});
}
Редактировать: как предложил @Aleksey L., вы можете передавать порождение args
как отдельные строковые аргументы, а не как массив.
const runProcess = (command: string, ...args: string[]) => {
const proc = child_process.spawn(command, args, {
stdio: ["ignore", "pipe", "pipe"],
});
}
Комментарии:
1. Конечно, это позволяет определять переменные как массив, но расширение его с помощью оператора spread не успокаивает typescript:
TSError: ⨯ Unable to compile TypeScript: searchwidget_take2.ts:14:42 - error TS2556: Expected 1-3 arguments, but got 1 or more.
Выделение ошибки находится на объекте options . На самом деле это не проверка и проверка того, что объект options предназначен для интерпретации как options . Это может быть проблемой с типами узлов.2. Хорошо, вот почему я спросил, чего
spawn
ожидать. Похоже, что он ожидает только 1-3 аргумента, и ошибка в том, что в массиве может быть бесконечно много? Если это так, то нам нужно быть более конкретными в определении второго аргумента, чтобы он имел ограниченную длину, а не просто любой массив строк. Это правильно?3. @LindaPaiste вы можете
import child_process from 'child_process';
на игровой площадке, это работает4.
args
может быть определено как параметр rest, тогда значение по умолчанию может быть удалено, а аргументы могут быть переданы без определения массива на вызывающем сайте typescriptlang.org/play ? #code/ …5. @AlekseyL. Мне это нравится!