Необязательные параметры на основе условных типов

Можно ли сделать функцию обязательной или необязательной на основе условных типов в TypeScript?

Вот что у меня есть на данный момент:

const foo = <T extends string | number>(
    first: T,
    second: T extends string ? boolean : undefined
) => undefined;

foo('foo', true); // ok, as intended
foo(2, true); // not ok, as intended
foo(2, undefined); // ok, as intended
foo(2); // compiler error! I want this to be ok

Необязательные параметры - это функция времени выполнения (оценка и передача значения по умолчанию), на которую не может повлиять система типов.

SLaks 13.09.2018 18:31

Вместо этого вы можете использовать простой тип перегрузки.

SLaks 13.09.2018 18:34
18
2
6 506
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете сделать это в 3.1, используя Кортежи в остальных параметрах и выражениях распространения

const foo = <T extends string | number>(
  first: T, 
  ...a: (T extends string ? [boolean] : [undefined?])
) => undefined;

foo('foo', true); // ok, as intended
foo(2, true); // not ok, as intended
foo(2, undefined); // ok, as intended
foo(2); // ok

Но лучше использовать перегрузки.

function foo2(first: string, second: boolean) : undefined
function foo2(first: number, second?: undefined): undefined
function foo2<T>(first: T, second?: boolean): undefined{
  return undefined
}

foo2('foo', true); // ok, as intended
foo2(2, true); // not ok, as intended
foo2(2, undefined); // ok, as intended
foo2(2); // ok

Также вы можете использовать : [] вместо : [undefined?], если действительно хотите полностью удалить параметр.

ProdigySim 10.10.2019 21:11

@ProdigySim, есть ли способ сделать это с перегрузками так, как вы описали?

Julien 28.04.2020 17:45

Важно отметить, что при использовании решения из первой половины этого ответа параметр a обернут в массив, что означает, что вам необходимо повторно назначить через a[0] или использовать с ...a.

Julien 28.04.2020 18:17

@Julien Ага, тебе нужно попасть в массив. Вот почему простые перегрузки обычно являются лучшим решением.

Titian Cernicova-Dragomir 28.04.2020 20:43

Меня больше всего интересует то, что @ProdigySim упомянул в первом комментарии здесь, что позволяет использовать условно необходимые аргументы. Есть ли способ получить условно необходимые аргументы с помощью перегрузок?

Julien 29.04.2020 15:26

Вы бы просто оставили аргумент в стороне от перегрузки. function foo2(first: number): undefined;

ProdigySim 04.05.2020 01:53

@ProdigySim Первоначальный запрос заключался в том, что undefined можно передать в качестве второго аргумента, но если это так, первым аргументом должно быть число. Это был вопрос в вопросе, поэтому я написал его именно так.

Titian Cernicova-Dragomir 04.05.2020 07:58

Другие вопросы по теме