Как я могу заставить TypeScript вывести значение для ограниченного типа generi c при указании дополнительных типов? - PullRequest
3 голосов
/ 20 июня 2020

В TypeScript у меня есть функция, которая принимает общий параметр c с ограничениями:

function f1<U extends string>(param: U): U {
  return param;
}

const a1 = f1('hello');
// a1's type is 'hello' -- Great!

Теперь я пытаюсь сделать так, чтобы вы могли дополнительно добавить другой тип как часть тип возврата. Однако, когда я это сделаю, я должен указать параметр по умолчанию для типа U. Это делает так, что TypeScript перестает выводить значение U и использует тип по умолчанию, который я предоставляю:

function f2<T = never, U extends string = string>(param: U): U | T {
  return param;
}

const b1 = f2('hello');
// b1's type is 'hello' -- Great!

const b2 = f2<boolean>('hello');
// b2's type is string | boolean -- Terrible: I want the type to be 'hello' | boolean.

const b3 = f2<boolean, 'hello'>('hello');
// b3's type is 'hello' | boolean -- Poor: The type is correct but API is redundant.

Итак, мой вопрос: есть ли способ, которым я могу заставить TypeScript выводить тип из параметр ? Я не хочу указывать тип по умолчанию для U, я всегда хочу, чтобы TypeScript выводил это значение. Псевдокод, который показывает полный API, как бы я хотел:

function f3<T = never, U extends string = infer>(param: U): U | T {
  return param;
}

const c1 = f3('hello');
// c1's type is 'hello' -- Great!

const c2 = f3<boolean>('hello');
// c2's type is 'hello' | boolean -- Great!

1 Ответ

2 голосов
/ 20 июня 2020

К сожалению, это невозможно. Существует PR для добавления частичного вывода с использованием сигилы _, но он довольно долго был неактивен.

Единственное решение - использовать каррирование функции, чтобы получить такое поведение, хотя и не идеален:

function f2<T = never>() {
  return function <U extends string = string>(param: U): U | T {
    return param;
  }
}
const b2 = f2<boolean>()('hello');
// b2's type is string | 'hello' 

Playground Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...