Возвращает ввод функции, если он расширяет общий тип, в противном случае null

#typescript

#typescript

Вопрос:

Я пытаюсь ввести функцию фильтра, которая принимает общий параметр и обеспечивает, чтобы возвращаемый тип заданной функции был либо вводом, если он соответствует общему, либо null если нет.

 type A = { type: 'A' };
type B = { type: 'B' };

type Union = A | B;
const filter = <T extends Union>(filter: <E extends Union>(item: E) => E extends T ? E : null) => {
  // something
};

filter<A>((item) => { 
// Argument of type '<E extends Union>(item: E) => E | null' is not assignable to parameter of type '<E extends Union>(item: E) => E extends A ? E : null'. 
// Type 'E | null' is not assignable to type 'E extends A ? E : null'. 
// Type 'null' is not assignable to type 'E extends A ? E : null'.(2345)
  if (item.type === 'A') return item;

  return null;
});
 

Я не совсем понимаю, почему это не работает. Я полагаю, что сообщение об ошибке немного вводит в заблуждение, я подозреваю, что TS не понимает, что if (item.type === 'A') return item; на самом деле удовлетворяет E extends A ? E части?

Я полагаю, я мог бы также использовать защиту типа, но это не обеспечило бы возврат всех типов T .

Игровая площадка Typescript

Ответ №1:

Я не уверен, что понимаю, почему возвращаемый тип filter функции должен быть E extends T ? E : null . В нем есть условие, не уверен, что это разрешено.

Эта упрощенная версия компилируется:

 type A = { type: 'A' };
type B = { type: 'B' };

type Union = A | B;
const filter = (filter: <E extends Union>(item: E) => E | null) => {
  // something
};



filter((item) => {
  if (item.type === 'A') return item;

  return null;
});

 

Комментарии:

1. Правильно, это не обязательно E extends T ... , но я хочу убедиться, что он возвращается item , только если он соответствует типу, переданному в as T и null или что-то еще, что я могу различить в противном случае.